2010-09-29 74 views
6

我有项目作为设置下面。我想删除一个项目,我得到如下:grails删除的对象将被重新保存级联错误

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) 

有没有什么办法让Hibernate来告诉我哪个对象具有参考回到那个将重新保存的项目对象。导致此循环异常的项目设置出了什么问题?

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 

    } 
} 

回答

9

Infact,您在Employee类中完成映射的方式 projects cascade:"all,delete-orphan"

你只需要做:

def employee = project.employee; 
employee.removeFromProjects(project); 

,该项目将被删除。 有关更多详细信息,请参阅GORM Gotchas By Peter Ledbrook。 它是一个3部分组成的系列,并解释了许多类似的情况

+2

我终于搞定了。事实并非如此简单。我认为,如果项目存储在SortedSet中,那么存在一个grails错误,那么它很难做到这一点。我不得不复制这些项目,删除我想删除的项目,然后将它们添加回员工以使其工作 – Derek 2010-10-01 17:39:15

0

如果您有级联删除设置,就像您一样,您需要在删除对象之前从其父级删除对象,然后才能删除它。从ProcectController中的堆栈跟踪在第50行左右。

+0

当你说“从其父母删除对象”这是否意味着对于这个检查我需要从员工中删除项目,或者我明确必须去树上删除所有对象将被删除从他们的父母? – Derek 2010-09-30 12:50:33

+0

下面是我如何从ProjectController中删除:def employee = project.employee; \t employee.removeFromProjects(project); project.delete(flush:true) – Derek 2010-09-30 13:09:48

5

我知道已经晚了,但有人可能会想在这里找到这样的: 会发生什么事是,Hibernate使用“dirtyChecking”,如GORM Gotchas By Peter Ledbrook解释。

为了使事情短: 休眠,所以Grails将要save()在Hibernate会话结束时employee对象(在你的情况下,在.delete(flush:true)调用),因为它检测到物体已经被修改(一project已被压制)。并且employee必须保持一个朝向project的链接,导致Hibernate感觉你会将delete()project改为save()它又回来了。

要解决此:

def employee = project.employee; 
employee.discard(); 
project.delete(flush:true); 

这告诉Hibernate不要save()employee没有你自讨苦吃。

相关问题