Grails/GORM中出错:已删除的对象将通过级联重新保存

Grails/GORM中出错:已删除的对象将通过级联重新保存,grails,gorm,Grails,Gorm,看起来这已经被问过很多次了,我已经研究过其中的一些问题,包括彼得·莱德布鲁克的“”一词,但在我的案例中似乎仍然无法理解。我有一个用户,它有许多项目,而项目属于用户。还有一个技能,它有许多与之相关联的项目,但是项目不属于技能。当我试图从用户中删除项目时,会出现该错误。域类如下所示: package grailstuts class User { String name static constraints = { name(nullable: true)

看起来这已经被问过很多次了,我已经研究过其中的一些问题,包括彼得·莱德布鲁克的“”一词,但在我的案例中似乎仍然无法理解。我有一个
用户
,它有许多
项目
,而
项目
属于
用户
。还有一个
技能
,它有许多与之相关联的
项目
,但是
项目
不属于
技能
。当我试图从
用户
中删除
项目
时,会出现该错误。域类如下所示:

package grailstuts class User { String name static constraints = { name(nullable: true) } static mapping = { projects cascade: "all-delete-orphan" } static hasMany = [ projects: Project ] } 给出的第一个
:。。。什么时候:。。。然后:…
上述测试中的块验证为良好。在第二个
when:…
块中,当我尝试从
用户中删除
项目
时,即出现错误时。错误看起来像这样

| Running 1 integration test... 1 of 1 | Failure: adding and deleting projects(grailstuts.SkillIntegrationSpec) | org.springframework.dao.InvalidDataAccessApiUsageException: deleted object would be re-saved by cascade (remove deleted object from associations): [grailstuts.Project#2]; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [grailstuts.Project#2] at org.grails.datastore.gorm.GormStaticApi.methodMissing_closure2(GormStaticApi.groovy:102) at grailstuts.SkillIntegrationSpec.adding and deleting projects(SkillIntegrationSpec.groovy:34) Caused by: org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [grailstuts.Project#2] ... 2 more | Completed 1 integration test, 1 failed in 0m 0s | Tests FAILED - view reports in C:\Grails\grailstuts\target\test-reports |正在运行1集成测试。。。第1页,共1页 |失败:添加和删除项目(grailstuts.SkillIntegrationSpec) |org.springframework.dao.InvalidDataAccessApiUsageException:删除的对象将通过级联重新保存(从关联中删除删除的对象):[grailstuts.Project#2];嵌套的异常是org.hibernate.ObjectDeletedException:删除的对象将通过级联重新保存(从关联中删除删除的对象):[grailstuts.Project#2] 位于org.grails.datastore.gorm.GormStaticApi.methodMissing_closure2(GormStaticApi.groovy:102) 在grailstuts.SkillIntegrationSpec.adding和deleting项目(SkillIntegrationSpec.groovy:34) 原因:org.hibernate.ObjectDeletedException:删除的对象将通过级联重新保存(从关联中删除删除的对象):[grailstuts.Project#2] ... 还有两个 |已完成1个集成测试,1个在0米0秒内失败 |测试失败-在C:\Grails\grailstuts\target\test reports中查看报告 我正在使用:

Grails version: 2.3.1 Groovy version: 2.1.8 JVM version: 1.7.0_45 Grails版本:2.3.1 Groovy版本:2.1.8 JVM版本:1.7.0_45
我花了相当多的时间寻找解决方案,但还没有运气。任何帮助都将不胜感激。谢谢大家!

所有删除孤立项
-仅适用于一对多关联和 表明 从关联中删除子项时,应自动将其删除 . 当 父母是。因此,当您调用
foundUser.removeFromProjects(foundProject1)
时,您试图删除
foundProject1
对象,但无法从数据库中删除它,因为
Skill
实体仍然引用此项目。如何修复它:

  • 第一种方法:从
    User
    中删除
    projects级联:“all delete orphan”
    以防止在调用
    User.removeFromProjects(…)
  • 第二种方法:调用
    skill.removeFromProjects(…)
    保存项目,以便删除项目

谢谢@araxn1d,您的解释简单、易懂,而且简单优雅——第一次尝试就成功了。这两种方法都很有效。在我的例子中,当我删除一个
项目时,我还希望它从数据库中删除,因此第二种方法适用。但是谢谢你从两个方面解释,它提供了一个完整的画面,并且更清楚地说明了在这种情况下整个事情是如何运作的。根据您的解释,我似乎也不需要
技能
类中的
静态映射={projects cascade:“all delete orphan”}
,而且我确实不需要它!非常感谢。我很高兴我帮助了你。祝你的grails应用程序开发好运=)谢谢,@araxn1d。看起来在我之前的多次尝试中,我尝试过类似于第二种方法的东西。但是,它不起作用,因为我试图删除多个项目,我试图先从各自的用户中删除所有项目,然后尝试从关联中删除项目,但这不起作用。当我用另一种方式做的时候,意思是先从协会中移除,然后再从父母那里移除,这是有效的。因此,顺序似乎很重要,现在也有意义了。非常感谢您的清晰简洁的解释! package grailstuts import spock.lang.* class SkillIntegrationSpec extends Specification { void "adding and deleting projects"() { given: "A user, and projects added to the user" def user = new User().save(failOnError: true) def project1 = new Project(title: "java, groovy") def project2 = new Project(title: "java, scala") user.addToProjects(project1) user.addToProjects(project2) when: "Projects are also added to skill entry" def java = new Skill(name: 'java').save(failOnError: true) java.addToProjects(project1) java.addToProjects(project2) def groovy = new Skill(name: 'groovy').save(failOnError: true) groovy.addToProjects(project1) def scala = new Skill(name: 'scala').save(failOnError: true) scala.addToProjects(project2) then: "Each skill entry has its corresponding projects" Skill.findByName("java").projects.size() == 2 Skill.findByName("groovy").projects.size() == 1 Skill.findByName("scala").projects.size() == 1 when: "Some projects are deleted from the database" def foundUser = User.get(user.id) def foundProject1 = Project.findByTitle("java, groovy") foundUser.removeFromProjects(foundProject1) then: "The deleted projects are also reflected in the skill entry" Skill.findByName("java").projects.size() == 1 Skill.findByName("groovy").projects.size() == 0 Skill.findByName("scala").projects.size() == 1 } } | Running 1 integration test... 1 of 1 | Failure: adding and deleting projects(grailstuts.SkillIntegrationSpec) | org.springframework.dao.InvalidDataAccessApiUsageException: deleted object would be re-saved by cascade (remove deleted object from associations): [grailstuts.Project#2]; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [grailstuts.Project#2] at org.grails.datastore.gorm.GormStaticApi.methodMissing_closure2(GormStaticApi.groovy:102) at grailstuts.SkillIntegrationSpec.adding and deleting projects(SkillIntegrationSpec.groovy:34) Caused by: org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [grailstuts.Project#2] ... 2 more | Completed 1 integration test, 1 failed in 0m 0s | Tests FAILED - view reports in C:\Grails\grailstuts\target\test-reports Grails version: 2.3.1 Groovy version: 2.1.8 JVM version: 1.7.0_45