最近,我为应用程序中的大多数实体(至少是我需要的实体)实现了软删除。实现如下所示:
Goal.groovy
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
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
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
@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目标的感知+与感知相关的等级对象的数量。当我试图删除这样一个目标时,我得到了一个例外:
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‘呢?
发布于 2015-03-24 06:41:14
您得到了异常,因为Rank有一个对Perception的引用,但是没有在任何一方指定belongsTo。
您可以在Rank中看到以下内容:
Perception left这就是为什么你要得到Column 'left_id' cannot be null. Stacktrace follows...。
因此,要解决这个问题,可以删除具有r/ship的rank对象,删除每个perception,或者在Rank中指定belongsTo = [left: Perception]。
https://stackoverflow.com/questions/29221459
复制相似问题