我有这两个域类:
class User {
String username
String password
static hasMany = [organizations: Organization]
static belongsTo = Organization
static constraints = {
username blank: false, unique: true
password blank: false
}
static mapping = {
password column: '`password`'
organizations fetch: 'join'
}
def beforeDelete() {
User.withNewSession {
this.organizations.each {
it.removeFromMembers(this)
}
this.save()
}
}
}
class Organization {
String name;
static hasMany = [members: User]
}
我想要实现的是我认为很清楚——我希望能够删除一个用户,但在此之前,我必须从分配给他的所有组织中删除该用户。GORM 显然不支持这一点,所以我尝试在 User 类上编写 beforeDelete 事件,该事件将在删除之前从所有组织中删除用户。问题是上面的代码不起作用,这是它抛出的异常:
| Error 2012-10-10 16:27:56,898 [http-bio-8080-exec-2] ERROR errors.GrailsExceptionResolver - NonUniqueObjectException occurred when processing request: [POST] /theses-management/user/index - parameters:
id: 1
_action_delete: Delete
a different object with the same identifier value was already associated with the session: [com.redhat.theses.auth.User#1]. Stacktrace follows:
Message: a different object with the same identifier value was already associated with the session: [com.redhat.theses.auth.User#1]
Line | Method
->> 36 | doCall in com.redhat.theses.auth.User$_beforeDelete_closure1$$ENlS7bOi
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 32 | beforeDelete in com.redhat.theses.auth.User$$ENlS7bOi
| 46 | onApplicationEvent in org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
| 93 | delete in com.redhat.theses.auth.UserController$$ENlS7klM
| 195 | doFilter . . . . . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1110 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . in java.lang.Thread
所以我厌倦了像这样更改 beforeDelete 事件:
def beforeDelete() {
User.withNewSession {
this.organizations.each {
it.removeFromMembers(this)
}
this.merge()
this.save()
}
}
但是随后抛出了相同的异常......
另一种尝试是这样的:
def beforeDelete() {
User.withNewSession {
this.organizations.each {
it.removeFromMembers(this)
}
def user = this.merge()
user.save()
}
}
结果是这个例外:
| Error 2012-10-10 16:33:22,669 [http-bio-8080-exec-7] ERROR util.JDBCExceptionReporter - Referential integrity constraint violation: "FK6BC87A0D3E1F37F9: PUBLIC.ORGANIZATION_MEMBERS FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID)"; SQL statement:
delete from user where id=? and version=? [23503-164]
| Error 2012-10-10 16:33:22,673 [http-bio-8080-exec-7] ERROR events.PatchedDefaultFlushEventListener - Could not synchronize database state with session
Message: could not delete: [com.redhat.theses.auth.User#1]
Line | Method
->> 93 | delete in com.redhat.theses.auth.UserController$$ENlS7klM
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 195 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run in java.lang.Thread
Caused by JdbcSQLException: Referential integrity constraint violation: "FK6BC87A0D3E1F37F9: PUBLIC.ORGANIZATION_MEMBERS FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID)"; SQL statement:
delete from user where id=? and version=? [23503-164]
->> 329 | getJdbcSQLException in org.h2.message.DbException
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 169 | get in ''
| 146 | get . . . in ''
| 398 | checkRow in org.h2.constraint.ConstraintReferential
| 415 | checkRowRefTable in ''
| 291 | checkRow in ''
| 862 | fireConstraints in org.h2.table.Table
| 879 | fireAfterRow in ''
| 99 | update . in org.h2.command.dml.Delete
| 73 | update in org.h2.command.CommandContainer
| 226 | executeUpdate in org.h2.command.Command
| 143 | executeUpdateInternal in org.h2.jdbc.JdbcPreparedStatement
| 129 | executeUpdate in ''
| 105 | executeUpdate in org.apache.commons.dbcp.DelegatingPreparedStatement
| 93 | delete . in com.redhat.theses.auth.UserController$$ENlS7klM
| 195 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run in java.lang.Thread
| Error 2012-10-10 16:33:22,680 [http-bio-8080-exec-7] ERROR errors.GrailsExceptionResolver - JdbcSQLException occurred when processing request: [POST] /theses-management/user/index - parameters:
id: 1
_action_delete: Delete
Referential integrity constraint violation: "FK6BC87A0D3E1F37F9: PUBLIC.ORGANIZATION_MEMBERS FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID)"; SQL statement:
delete from user where id=? and version=? [23503-164]. Stacktrace follows:
Message: Referential integrity constraint violation: "FK6BC87A0D3E1F37F9: PUBLIC.ORGANIZATION_MEMBERS FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID)"; SQL statement:
delete from user where id=? and version=? [23503-164]
Line | Method
->> 329 | getJdbcSQLException in org.h2.message.DbException
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 169 | get in ''
| 146 | get . . . . . . . . . in ''
| 398 | checkRow in org.h2.constraint.ConstraintReferential
| 415 | checkRowRefTable . . in ''
| 291 | checkRow in ''
| 862 | fireConstraints . . . in org.h2.table.Table
| 879 | fireAfterRow in ''
| 99 | update . . . . . . . in org.h2.command.dml.Delete
| 73 | update in org.h2.command.CommandContainer
| 226 | executeUpdate . . . . in org.h2.command.Command
| 143 | executeUpdateInternal in org.h2.jdbc.JdbcPreparedStatement
| 129 | executeUpdate . . . . in ''
| 105 | executeUpdate in org.apache.commons.dbcp.DelegatingPreparedStatement
| 93 | delete . . . . . . . in com.redhat.theses.auth.UserController$$ENlS7klM
| 195 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter . . . . . . in grails.plugin.cache.web.filter.AbstractFilter
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run in java.lang.Thread
你知道我可能做错了什么吗?
提前感谢您的回答。