首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >尝试执行带有关系的实体的软删除会导致异常

尝试执行带有关系的实体的软删除会导致异常
EN

Stack Overflow用户
提问于 2015-03-23 22:14:44
回答 1查看 351关注 0票数 1

最近,我为应用程序中的大多数实体(至少是我需要的实体)实现了软删除。实现如下所示:

Goal.groovy

代码语言:javascript
运行
复制
class Goal {

   String definition;
   Account account;
   boolean tmpl = false;
   String tmplName;

   Goal template

   Timestamp dateCreated
   Timestamp lastUpdated
   Timestamp deletedAt

   static belongsTo = [
      account: Account,
      template: Goal
   ]

   static hasMany = [perceptions: Perception, sessions: RankingSession]

   static mapping = {
      autoTimestamp true

      table 'goal'

      definition type: 'text'
      tmplName column: '`tmpl_name`'
      perceptions sort:'title', order:'asc'
      dateCreated column: 'date_created'
      lastUpdated column: 'last_updated'
      deletedAt column: 'deleted_at'
   }
   ...
   def beforeDelete() {
      if (deletedAt == null) {
         Goal.executeUpdate('update Goal set deletedAt = ? where id = ?', [new Timestamp(System.currentTimeMillis()), id])
      }

      return false
   }
   ...

Perception.groovy

代码语言:javascript
运行
复制
class Perception {

   String title
   String definition
   Goal goal

   Timestamp dateCreated
   Timestamp lastUpdated
   Timestamp deletedAt

   static hasMany = [left: Rank, right: Rank]
   static mappedBy = [left: "left", right: "right"]

   static belongsTo = [goal: Goal]

   static namedQueries = {
      notDeleted {
         isNull 'deletedAt'
      }
   }

   static mapping = {
      autoTimestamp true

      table 'perception'

      definition type: 'text'
      dateCreated column: 'date_created'
      lastUpdated column: 'last_updated'
      deletedAt column: 'deleted_at'
   }

   static constraints = {
      title blank: false, size: 1..255
      definition nullable: true, blank: true, size: 1..5000
      goal nullable: false
      lastUpdated nullable: true
      deletedAt nullable: true
   }

   /**
    * before delete callback to prevent physical deletion
    *
    * @return
    */
   def beforeDelete() {
      if (deletedAt == null) {
         Perception.executeUpdate('update Perception set deletedAt = ? where id = ?', [new Timestamp(System.currentTimeMillis()), id])
      }

      return false
   }
}

Rank.groovy

代码语言:javascript
运行
复制
class Rank {

   Perception left
   Perception right

   Integer leftRank
   Integer rightRank

   RankingSession session

   static belongsTo = [session: RankingSession]

   static mapping = {
      table 'rank'
   }

   static constraints = {
      leftRank range: 0..1, nullable: true 
      rightRank range: 0..1, nullable: true
      left nullable: false
      right nullable: false
      session nullable: false
   }
}

我的问题发生在删除(逻辑删除)。我通过服务类执行删除的方式如下:

GoalService.groovy

代码语言:javascript
运行
复制
@Transactional
class GoalService {

   /**
    * Deletes goal 
    * 
    * @param goal
    * @return
    */
   def deleteGoal(Goal goal) {
      if (goal.tmpl == true) {
         throw new ValidationException("Provided object is a template!")
      }

      def perceptions = Perception.notDeleted.findAllByGoal(goal)
      for (perception in perceptions) {
         perception.delete()
      }

      goal.delete()
   }
}

我有一个用例,它在一种情况下工作,在另一种情况下处理异常。

#1现有的目标和分配给它的感知的数量。删除按预期工作:目标和感知被标记为已删除。

#2目标的感知+与感知相关的等级对象的数量。当我试图删除这样一个目标时,我得到了一个例外:

代码语言:javascript
运行
复制
    Error 2015-03-23 14:52:10,294 [http-nio-8080-exec-9] ERROR spi.SqlExceptionHelper  - Column 'left_id' cannot be null
| Error 2015-03-23 14:52:10,357 [http-nio-8080-exec-9] ERROR errors.GrailsExceptionResolver  - MySQLIntegrityConstraintViolationException occurred when processing request: [POST] /triz/rrm/goal/1/delete - parameters:
SYNCHRONIZER_TOKEN: 57fda8f2-8025-45e0-ac60-592234f54ef1
SYNCHRONIZER_URI: /triz/rrm/goals
Column 'left_id' cannot be null. Stacktrace follows:
Message: Column 'left_id' cannot be null
    Line | Method
->>  411 | handleNewInstance  in com.mysql.jdbc.Util
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    386 | getInstance        in     ''
|   1041 | createSQLException in com.mysql.jdbc.SQLError
|   4237 | checkErrorPacket   in com.mysql.jdbc.MysqlIO
|   4169 | checkErrorPacket . in     ''
|   2617 | sendCommand        in     ''
|   2778 | sqlQueryDirect . . in     ''
|   2834 | execSQL            in com.mysql.jdbc.ConnectionImpl
|   2156 | executeInternal .  in com.mysql.jdbc.PreparedStatement
|   2441 | executeUpdate      in     ''
|   2366 | executeUpdate . .  in     ''
|   2350 | executeUpdate      in     ''
|    129 | doCall . . . . . . in triz.rrm.RrmGoalController$_delete_closure5
|    127 | delete             in triz.rrm.RrmGoalController

我已经试过了一切,包括:

  • 物理上删除了所有约束
  • 在关系中使用“级联:‘保存-更新’”

没有任何帮助,我唯一能理解的事实是它与级联有关,但如果实际上我正在更新对象,那么GORM为什么要级联'delete‘呢?

EN

回答 1

Stack Overflow用户

发布于 2015-03-24 06:41:14

您得到了异常,因为Rank有一个对Perception的引用,但是没有在任何一方指定belongsTo

您可以在Rank中看到以下内容:

代码语言:javascript
运行
复制
Perception left

这就是为什么你要得到Column 'left_id' cannot be null. Stacktrace follows...

因此,要解决这个问题,可以删除具有r/ship的rank对象,删除每个perception,或者在Rank中指定belongsTo = [left: Perception]

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29221459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档