Error in Grails/GORM: deleted object would be re
Looks like this has been asked many many times before, and I have looked into several of those, including the "GORM Gotchas (Part 2)" by Peter Ledbrook, but still cannot seem to figure it out in my case. I have a user which has many projects , and a project belongs to a user . Then there is a skill which has many projects associated with it, but a project does NOT belong to a skill . When I try to remove a project from a user , I get that error. The domain classes are as follows:
package grailstuts
class User {
String name
static constraints = { name(nullable: true) }
static mapping = { projects cascade: "all-delete-orphan" }
static hasMany = [ projects: Project ]
}
package grailstuts
class Project {
String title
static constraints = { title(nullable: true) }
static belongsTo = [ user: User ]
}
package grailstuts
class Skill {
String name
static constraints = { name(nullable: true) }
static mapping = { projects cascade: "all-delete-orphan" }
static hasMany = [ projects: Project ]
}
When I run the integration test as follows, the part containing foundUser.removeFromProjects(foundProject1) seems to have the issue.
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
}
}
The first given:... when:... then:... block in the above test verifies fine. In the second when:... block when I try to remove the project from the user , that is when the error seem to occur. The error looks something like this ...
| 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:Grailsgrailstutstargettest-reports
I am using:
Grails version: 2.3.1
Groovy version: 2.1.8
JVM version: 1.7.0_45
Have spent quite a bit of time digging for some solution, but no luck yet. Any help would be highly appreciated. Thank you!
all-delete-orphan - Applies only to one-to-many associations and indicates that when a child is removed from an association then it should be automatically deleted . Children are also deleted when the parent is. So when you call foundUser.removeFromProjects(foundProject1) you are trying to delete foundProject1 object but it cannot be deleted from DB becouse Skill entity still have reference this project. How to fix it:
projects cascade: "all-delete-orphan" from User to prevent deleting projects when you call user.removeFromProjects(...) skill.removeFromProjects(...) with the save project so the project will be deleted 上一篇: 符合标准的Grails
