Удаленный объект Grails будет повторно сохранен при каскадной ошибке - PullRequest
6 голосов
/ 30 сентября 2010

У меня есть проект, как показано ниже.Я пытаюсь удалить проект, и я получаю следующее:

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

    }
}

Ответы [ 3 ]

9 голосов
/ 01 октября 2010

Infact, как вы сделали отображение projects cascade:"all,delete-orphan" в классе Employee.

Вам просто нужно сделать:

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

И проект будет удален какЧто ж.Для получения более подробной информации см. GORM Gotchas By Peter Ledbrook .Это 3 части серии и объясняет много похожих ситуаций

5 голосов
/ 04 октября 2011

Я знаю, что уже поздно, но кто-то может захотеть найти это здесь: Что происходит, так это то, что Hibernate использует «dirtyChecking», как объяснено в GORM Gotchas By Peter Ledbrook .

Чтобы сделать вещи короткими: Hibernate, и поэтому Grails захочет save() employee объект в конце сеанса Hibernate (в вашем случае при вызове .delete(flush:true)), потому что он обнаруживает, что объект был изменен (project был подавлено). И employee, должно быть, сохранил связь с project, в результате чего Hibernate почувствовал, что вы delete() project вернете его обратно.

Чтобы обойти это:

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

Это говорит Hibernate не save() employee без вашего ведома.

0 голосов
/ 30 сентября 2010

если у вас есть каскад для установки удаления, как и у вас, вам нужно удалить объект, который нужно удалить, из его родительского объекта перед его удалением. От вашей трассировки стека в ProcectController около строки 50.

...