【问题标题】:grails deleted object would be re-saved by cascade error级联错误将重新保存 grails 删除的对象
【发布时间】: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

    }
}

【问题讨论】:

    标签: hibernate grails-orm grails


    【解决方案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 Ledbrook。 它是一个 3 部分系列,并解释了许多类似的情况

    【讨论】:

    • 我终于让它工作了。事实上并没有那么简单。我认为如果项目存储在 SortedSet 中,则存在一个 grails 错误,然后很难进行删除。我必须制作项目的副本,删除我想删除的项目,然后将它们添加回员工以使其正常工作
    【解决方案3】:

    我知道现在很晚了,但有人可能想在这里找到这个: 正如GORM Gotchas By Peter Ledbrook 中所解释的那样,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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-15
      • 2014-03-31
      • 2019-06-30
      • 2012-07-23
      相关资源
      最近更新 更多