Я просто не понимаю, почему Hibernate выдает исключение, упомянутое в заголовке. Я, вероятно, не понимаю идею управления состоянием, лежащую в основе Hibernate.
У меня следующая ситуация:
Отношение "один ко многим" между организацией и сотрудником
Организация.hmb.xml
<set name="employees" inverse="true" cascade="save-update">
<key column="organization_id"/>
<one-to-many class="Employee"/>
</set>
Сотрудник.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
EDIT: сначала я не упомянул, что операция удаления на уровне службы является транзакционной, что кажется важной информацией (продолжайте читать)!
Спящий режим бросает...
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 вообще заботится о каскаде в родительском классе?
Где находится точка выполнения, в которой он рассматривает каскад на объекте Organization? Почему он просто не может удалить Employee(Child) с помощью DELETE FROM... и все. Кроме того, Сотрудник является владельцем отношения, и операции, выполняемые над ним, должны управлять самим отношением. Когда он вообще думал вызывать какую-либо операцию над объектом Organization в упомянутом сценарии? Я просто не понимаю.