级联错误将重新保存 grails 删除的对象
Posted
技术标签:
【中文标题】级联错误将重新保存 grails 删除的对象【英文标题】:grails deleted object would be re-saved by cascade error 【发布时间】:2011-04-19 01:15:07 【问题描述】:我的项目设置如下。我正在尝试删除一个项目,我得到以下信息:
2010-09-29 11:45:22,902 [http-8080-1] ERROR errors.GrailsExceptionResolver - deleted object would be re-saved by cascade (remove deleted object from associatio
ns): [Project#204]
org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [Project#204]
at ProjectController$_closure6.doCall(ProjectController:50)
at ProjectController$_closure6.doCall(ProjectController)
at org.jsecurity.web.servlet.JSecurityFilter.doFilterInternal(JSecurityFilter.java:382)
at org.jsecurity.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:180)
at java.lang.Thread.run(Thread.java:619)
有什么方法可以让休眠状态告诉我哪个对象具有对将被重新保存的 Project 对象的引用。我的项目设置有什么问题导致此循环异常?
public class Project implements Comparable
static belongsTo = [employee:Employee]
static hasMany = [roles:Role]
static constraints =
static mapping =
description type:"text"
roles lazy:false, cascade:"all,delete-orphan"
client lazy:false, cascade:"all,delete-orphan"
employer lazy:false, cascade:"all,delete-orphan"
class Employee implements Comparable
static hasMany = [employeeDesiredSkills:EmployeeDesiredSkill,
employeeDesiredTools:EmployeeDesiredTool,
employeeAreasOfExpertise:EmployeeAreaOfExpertise,
projects:Project,
education:Education]
static mapping =
employeeDesiredSkills cascade:"all,delete-orphan", lazy:false
employeeDesiredTools cascade:"all,delete-orphan", lazy:false
education cascade:"all,delete-orphan", lazy:false
projects cascade:"all,delete-orphan", lazy:false
public class Role implements Comparable
static belongsTo = [project:Project]
static hasMany = [roleSkills:RoleSkill,roleTools:RoleTool]
static mapping =
duties type:"text"
roleSkills cascade:"all,delete-orphan", lazy:false
roleTools cascade:"all,delete-orphan", lazy:false
locationType cascade:"all,delete-orphan", lazy:false
static contraints =
endDate(nullable: true)
roleSkills(nullable: true)
roleTools(nullable: true)
class Employer implements Comparable
static mapping =
type lazy:false, cascade:"all,delete-orphan"
class RoleTool implements Comparable
static belongsTo = [role:Role, tool:Tool]//not sure this makes sense, but have to leave it or DB breaks
Tool tool = new Tool(name:"")
static mapping =
tool cascade:"save-update", lazy:false
class RoleSkill implements Comparable
static belongsTo = [role:Role, skill:Skill]//not sure this makes sense, but have to leave it or DB breaks
Skill skill = new Skill(name:"")
static mapping =
skill cascade:"save-update", lazy:false
class Skill implements Comparable
static hasMany = [roleSkills:RoleSkill, employeeDesiredSkills:EmployeeDesiredSkill]
static mapping =
roleSkills cascade:"all,delete-orphan", lazy:false
employeeDesiredSkills cascade:"all,delete-orphan", lazy:false
class Tool implements Comparable
static hasMany = [roleTools:RoleTool, employeeDesiredTools:EmployeeDesiredTool]
static mapping =
roleTools cascade:"all,delete-orphan", lazy:false
employeeDesiredTools cascade:"all,delete-orphan", lazy:false
【问题讨论】:
【参考方案1】:如果您有级联删除设置,就像您一样,您需要在删除之前从其父级中删除要删除的对象。来自您在 ProcectController 中的堆栈跟踪,大约在第 50 行。
【讨论】:
当您说“要从其父对象中删除的对象”时,这是否意味着对于此示例,我需要从员工中删除项目,或者我是否必须明确地向下删除所有对象被父母删除? 这是我从 ProjectController 中删除的方法: def employee = project.employee;员工.removeFromProjects(项目); project.delete(flush:true)【参考方案2】:事实上,你完成映射的方式
projects cascade:"all,delete-orphan"
在 Employee 类中。
你只需要这样做:
def employee = project.employee;
employee.removeFromProjects(project);
该项目也将被删除。 更多详情请参考GORM Gotchas By Peter Led***。 它是一个 3 部分系列,并解释了许多类似的情况
【讨论】:
我终于让它工作了。事实上并没有那么简单。我认为如果项目存储在 SortedSet 中,则存在一个 grails 错误,然后很难进行删除。我必须制作项目的副本,删除我想删除的项目,然后将它们添加回员工以使其正常工作【参考方案3】:我知道现在很晚了,但有人可能想在这里找到这个: 正如GORM Gotchas By Peter Led*** 中所解释的那样,Hibernate 使用了“dirtyChecking”。
简而言之:
Hibernate,因此 Grails 将希望在 Hibernate 会话结束时 save()
employee
对象(在您的情况下,在 .delete(flush:true)
调用中),因为它检测到对象已被修改(project
已被压制)。并且employee
必须保持指向project
的链接,导致Hibernate 感觉您将delete()
和project
重新连接到save()
。
要解决此问题:
def employee = project.employee;
employee.discard();
project.delete(flush:true);
这告诉 Hibernate 不要在没有你要求的情况下使用 save()
employee
。
【讨论】:
以上是关于级联错误将重新保存 grails 删除的对象的主要内容,如果未能解决你的问题,请参考以下文章