示例项目:https://github.com/joemccall86/cascade-delete-test/tree/automatic-collection-purge
我不确定这是不是一个错误,因为我还没有看到它在任何地方工作的例子。
说我有以下域类:
class Organization {
String name
static hasMany = [
users: Person,
teams: Team
]
static mapping = {
users cascade: 'all-delete-orphan'
}
}
class Person {
String name
Organization organization
static belongsTo = [Organization, Team]
static hasMany = [teams: Team]
static constraints = {
}
def beforeDelete() {
Team.withNewSession {
removeFromAllTeams()
}
true
}
def removeFromAllTeams() {
Team.where {
members {
id == this.id
}
}.each { Team team ->
if (team.members.contains(this)) {
team.members.remove(this)
team.save()
}
}
}
}
class Team {
String name
static hasMany = [members: Person]
static belongsTo = [organization: Organization]
static constraints = {
}
}
根据https://spring.io/blog/2010/07/02/gorm-gotchas-part-2/(特别是关于多对多关系级联的部分),我需要在成功删除之前手动清除团队中的人员。这是通过方法removeFromAllTeams
完成的。
每次我打算删除用户时都会手动调用它(这通常会发生在服务调用中),但它看起来更像是属于域对象本身的beforeDelete
方法。但是当我把它放在那里时,我得到了:
SQL [n/a]; Referential integrity constraint violation: "FKGHKKY8WMH379RPMFH92T807RY: PUBLIC.TEAM_MEMBERS FOREIGN KEY(PERSON_ID) REFERENCES PUBLIC.PERSON(ID) (1)"; SQL statement:
delete from person where id=? and version=? [23503-194]; nested exception is org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FKGHKKY8WMH379RPMFH92T807RY: PUBLIC.TEAM_MEMBERS FOREIGN KEY(PERSON_ID) REFERENCES PUBLIC.PERSON(ID) (1)"; SQL statement:
delete from person where id=? and version=? [23503-194]
这是一个spock测试来说明我在做什么:
@Unroll
void "user is removed from team before deletion, runManually = #runManually"() {
given: 'an existing org'
Organization.withNewSession {
def organization = new Organization(name: 'Cyberdyne Systems').save(failOnError: true)
and: 'a person is added'
organization.addToUsers(name: 'John Connor').save(failOnError: true)
organization.save(failOnError: true, flush: true)
and: 'a new team is added to the org'
organization.addToTeams(name: 'IT').save(failOnError: true, flush: true)
and: 'the person is added to the team'
organization.teams.first().addToMembers(organization.users.first())
organization.save(failOnError: true, flush: true)
}
and: 'the person is deleted'
def userToDelete = Person.first()
if (runManually) {
userToDelete.removeFromAllTeams()
}
userToDelete.delete(flush: true)
expect: 'the team has no users'
Team.first().members.isEmpty()
and: 'there are no more users'
Person.count == 0
where:
runManually << [true, false]
}
我错过了什么?换句话说,是否有可能让域类在beforeDelete
内进行自己的关系清理?
答案 0 :(得分:0)
我在Grails 3.2.12和GORM 6.1.6.RELEASE中遇到过这个问题。
和您一样,我尝试将清理代码添加到beforeDelete
方法,但它没有用。根据我的提交日志:
&#34;出于某种原因,这不能在beforeDelete
中完成,可能是因为GORM在调用beforeDelete
&#34;之前检查删除是否有效。
我建议您在GitHub上创建一个问题,并要求Grails团队澄清这是一个错误还是一个功能。