hibernate grails删除的对象将被cascade错误重新保存

sqxo8psd  于 2023-05-29  发布在  其他
关注(0)|答案(4)|浏览(171)

我的项目设置如下。我尝试删除一个项目,结果如下:

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告诉我哪个对象有对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

    }
}
4ioopgfo

4ioopgfo1#

事实上,您在Employee类中完成Mapprojects cascade:"all,delete-orphan"的方式。
你只需要做:

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

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

ffdz8vbo

ffdz8vbo2#

我知道现在已经很晚了,但有人可能会喜欢这里:Hibernate使用了'dirtyChecking',如GORM Gotchas By Peter Ledbrook中所解释的。
长话短说:Hibernate,所以Grails会在Hibernate会话结束时(在本例中是在.delete(flush:true)调用时)save()employee对象,因为它检测到该对象已被修改(project已被抑制)。而且employee必须保持一个指向project的链接,使Hibernate感觉您将delete()project再次返回到save()
要解决此问题:

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

这告诉Hibernate不要在没有你要求的情况下save()employee

1u4esq0p

1u4esq0p3#

如果你有级联删除设置,就像你做的那样,你需要在删除对象之前从它的父对象中删除它。从ProcectController中的stacktrace,大约第50行。

e5nszbig

e5nszbig4#

这是因为在事务结束时,grails和hibernate会自动保存Parent对象,并且它检测到一个Child被删除,所以它不允许删除该Object。所以我们需要

child.parent.discard()
child.delete()

你可以参考这里https://pritomkumar.blogspot.com/2013/11/grails-deleted-object-would-be-re-saved.html它解决了我的问题。

相关问题