Удаление дочернего элемента в отношении «один ко многим» вызывает исключение ObjectDeletedException

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

У меня следующая ситуация:

Отношение «один ко многим» между организацией и сотрудником

Organization.hmb.xml

<set name="employees" inverse="true" cascade="save-update">  
    <key column="organization_id"/>  
    <one-to-many class="Employee"/>  
</set>

Employee.hbm.xml

<many-to-one name="organization" class="Organization"  column="organization_id" />

Я использую стандартную архитектуру приложения Spring / Hibernate со службами и DAO, где DAO расширяют класс HibernateDaoSupport и использовать службы класса HibernateTemplate для управления сеансом.

Когда я пытаюсь удалить сотрудника в этом сценарии ...

Employee e=employeeService.read(1); 

//EDIT: Important! delete operation in EmployeeService is (@)transactional  
employeeService.delete(e); //this call just delegate execution to employeeDao.delete

РЕДАКТИРОВАТЬ : Я не упомянул сначала, что операция удаления на уровне службы является транзакционной, что, похоже, будь важной информацией (продолжайте читать)!

Hibernate выбрасывает ...

 ObjectDeletedException: deleted object would be re-saved by cascade...

Операция удаления в EmployeeService выглядит так ...

  @Transactional public void delete(Employee emp){  
    Employee e=employeeDao.read(emp.getId());  
    if(e==null)  
        throw NoSuchOrganizationException();  

    /*...several while-s to delete relations where Employee is  
    not owner of relation... */

    employeeDao.delete(e);  
}

Сценарии (они не связаны):
1. Когда я удаляю cascade = "save-update" из сопоставления отношения с сотрудником (ами) в Organization.hbm.xml, все работает нормально .
xml

<set name="employees" inverse="true" cascade="save-update">  
    <key column="organization_id"/>  
    <one-to-many class="Employee"/>  
</set>

Employee.hbm.xml

<many-to-one name="organization" class="Organization"  column="organization_id" />

Я использую стандартную архитектуру приложения Spring / Hibernate со службами и DAO, где DAO расширяют класс HibernateDaoSupport и используют службы класса HibernateTemplate для управления сеансом.

Когда я пытаюсь удалить Employee в этот сценарий ...

Employee e=employeeService.read(1); 

//EDIT: Important! delete operation in EmployeeService is (@)transactional  
employeeService.delete(e); //this call just delegate execution to employeeDao.delete

РЕДАКТИРОВАТЬ : Я сначала не упомянул, что операция удаления на уровне обслуживания является транзакционной, что кажется важной информацией (продолжайте читать)!

Hibernate выбрасывает ...

 ObjectDeletedException: deleted object would be re-saved by cascade...

Операция удаления в EmployeeService выглядит так ...

  @Transactional public void delete(Employee emp){  
    Employee e=employeeDao.read(emp.getId());  
    if(e==null)  
        throw NoSuchOrganizationException();  

    /*...several while-s to delete relations where Employee is  
    not owner of relation... */

    employeeDao.delete(e);  
}

Сценарии (они не связаны):
1. Когда я удаляю cascade = "save-update" из сопоставления отношения с сотрудником (ами) в Organization.hbm.xml, все работает нормально .
xml

<set name="employees" inverse="true" cascade="save-update">  
    <key column="organization_id"/>  
    <one-to-many class="Employee"/>  
</set>

Employee.hbm.xml

<many-to-one name="organization" class="Organization"  column="organization_id" />

Я использую стандартную архитектуру приложения Spring / Hibernate со службами и DAO, где DAO расширяют класс HibernateDaoSupport и используют службы класса HibernateTemplate для управления сеансом.

Когда я пытаюсь удалить Employee в этот сценарий ...

Employee e=employeeService.read(1); 

//EDIT: Important! delete operation in EmployeeService is (@)transactional  
employeeService.delete(e); //this call just delegate execution to employeeDao.delete

РЕДАКТИРОВАТЬ : Я сначала не упомянул, что операция удаления на уровне обслуживания является транзакционной, что кажется важной информацией (продолжайте читать)!

Hibernate выбрасывает ...

 ObjectDeletedException: deleted object would be re-saved by cascade...

Операция удаления в EmployeeService выглядит так ...

  @Transactional public void delete(Employee emp){  
    Employee e=employeeDao.read(emp.getId());  
    if(e==null)  
        throw NoSuchOrganizationException();  

    /*...several while-s to delete relations where Employee is  
    not owner of relation... */

    employeeDao.delete(e);  
}

Сценарии (они не связаны):
1. Когда я удаляю cascade = "save-update" из сопоставления отношения с сотрудником (ами) в Organization.hbm.xml, все работает нормально .
где DAO расширяют класс HibernateDaoSupport и используют службы класса HibernateTemplate для управления сеансом.

Когда я пытаюсь удалить сотрудника в этом сценарии ...

Employee e=employeeService.read(1); 

//EDIT: Important! delete operation in EmployeeService is (@)transactional  
employeeService.delete(e); //this call just delegate execution to employeeDao.delete

РЕДАКТИРОВАТЬ : Я сначала не упомянул, что операция удаления на уровне обслуживания является транзакционным, что кажется важной информацией (продолжайте читать)!

Hibernate выбрасывает ...

 ObjectDeletedException: deleted object would be re-saved by cascade...

Операция удаления в EmployeeService выглядит так ...

  @Transactional public void delete(Employee emp){  
    Employee e=employeeDao.read(emp.getId());  
    if(e==null)  
        throw NoSuchOrganizationException();  

    /*...several while-s to delete relations where Employee is  
    not owner of relation... */

    employeeDao.delete(e);  
}

Сценарии (они не связаны):
1. Когда я удаляю cascade = "save-update" из сопоставления отношения с сотрудником (ами) в Organization.hbm.xml, все работает нормально .
где DAO расширяют класс HibernateDaoSupport и используют службы класса HibernateTemplate для управления сеансом.

Когда я пытаюсь удалить сотрудника в этом сценарии ...

Employee e=employeeService.read(1); 

//EDIT: Important! delete operation in EmployeeService is (@)transactional  
employeeService.delete(e); //this call just delegate execution to employeeDao.delete

РЕДАКТИРОВАТЬ : Я сначала не упомянул, что операция удаления на уровне обслуживания является транзакционным, что кажется важной информацией (продолжайте читать)!

Hibernate выбрасывает ...

 ObjectDeletedException: deleted object would be re-saved by cascade...

Операция удаления в EmployeeService выглядит так ...

  @Transactional public void delete(Employee emp){  
    Employee e=employeeDao.read(emp.getId());  
    if(e==null)  
        throw NoSuchOrganizationException();  

    /*...several while-s to delete relations where Employee is  
    not owner of relation... */

    employeeDao.delete(e);  
}

Сценарии (они не связаны):
1. Когда я удаляю cascade = "save-update" из сопоставления отношения с сотрудником (ами) в Organization.hbm.xml, все работает нормально .
Сначала я не упоминал, что операция удаления на уровне обслуживания является транзакционной, что кажется важной информацией (продолжайте читать)!

Hibernate выбрасывает ...

 ObjectDeletedException: deleted object would be re-saved by cascade...

Операция удаления в EmployeeService выглядит так ...

  @Transactional public void delete(Employee emp){  
    Employee e=employeeDao.read(emp.getId());  
    if(e==null)  
        throw NoSuchOrganizationException();  

    /*...several while-s to delete relations where Employee is  
    not owner of relation... */

    employeeDao.delete(e);  
}

Сценарии (они не связаны):
1. Когда я удаляю cascade = "save-update" из сопоставления отношения с сотрудником (ами) в Organization.hbm.xml, все работает нормально .
Сначала я не упоминал, что операция удаления на уровне обслуживания является транзакционной, что кажется важной информацией (продолжайте читать)!

Hibernate выбрасывает ...

 ObjectDeletedException: deleted object would be re-saved by cascade...

Операция удаления в EmployeeService выглядит так ...

  @Transactional public void delete(Employee emp){  
    Employee e=employeeDao.read(emp.getId());  
    if(e==null)  
        throw NoSuchOrganizationException();  

    /*...several while-s to delete relations where Employee is  
    not owner of relation... */

    employeeDao.delete(e);  
}

Сценарии (они не связаны):
1. Когда я удаляю cascade = "save-update" из сопоставления отношения с сотрудником (ами) в Organization.hbm.xml, все работает нормально .
2. Когда я удаляю аннотацию @Transactional из метода удаления, все работает нормально.
3. Когда я удаляю дочерний элемент (Сотрудник) из родительского (Организация) списка детей , а затем выполняю удаление, все работает нормально.

Вопрос :

Почему Hibernate вообще заботится о каскад в родительском классе ?
Где точка выполнения, в которой он рассматривает каскад на объекте организации ? Почему он просто не может удалить сотрудника (ребенка) с помощью DELETE FROM ... и все. Кроме того, Сотрудник является владельцем отношений, и выполняемые над ним операции должны сами управлять отношениями. Когда он вообще думал вызвать какую-либо операцию над объектом "Организация" в упомянутом сценарии ? Я просто не понимаю.

7
задан Brian Tompsett - 汤莱恩 24 July 2015 в 16:44
поделиться