слияние с гибернацией, вызывающее ошибку с грязными объектами

Я использую Hibernate с Spring в своем приложении. Я постоянно использую отсоединенные объекты и повторно присоединяю их всякий раз, когда мне нужно сделать вызовы в базу данных. Я использую шаблон гибернации, чтобы позаботиться об управлении соединениями для меня.

Моя структура данных выглядит следующим образом:

classA: 
   <one-to-many name="classB" inverse="true" cascade="all,delete-orphan" lazy="true">

classB:
   <one-to-many name="classC" inverse="true" cascade="all,delete-orphan" lazy="false" fetch="subselect">

Когда я делаю следующий вызов с потенциальным изменением некоторых элементов в классе B или классе C, я получаю сообщение об ошибке:

classA a = (classA)hibernateTemplate.merge(newClassA);

Ошибка, которую я получаю:

[11/10/08 12:08:39:126 EST] 00000024 SystemOut     O 2008-11-10 12:08:38,876  -  - ca.thedominion.cfa.persistence.hibernate.ClassADAOImpl  :updateClassA Technical Exception occurred: 
org.springframework.dao.InvalidDataAccessApiUsageException: deleted object would be re-saved by cascade (remove deleted object from associations): [ca...classC#715590]; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [ca...classC#715590]
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:639)
    at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
    at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
    at org.springframework.orm.hibernate3.HibernateTemplate.merge(HibernateTemplate.java:820)

Может кто-нибудь объяснить мне, почему это вызывает ошибку? Насколько я понимаю, слияние должно определить, какие объекты в дереве изменились, если таковые имеются, и обновить/удалить/вставить их, а не пытаться удалить и повторно вставить какие-либо другие. Но это, кажется, пытается удалить все элементы типа classC и повторно вставить их.


person Elie    schedule 10.11.2008    source источник


Ответы (1)


Судя по всему, вы удалили один из ваших classC, но он остался в одной из коллекций. Теперь Hibernate запутался, что делать: вы его удалили, а в коллекции стоит cascade="all" (включая сохранение, то есть), и вы собираетесь сохранить коллекцию (включая удаленный объект).

Вы должны удалить объект classC из коллекции вместо того, чтобы удалять его напрямую, или сделать и то, и другое (удалить и удалить из коллекции).

person Vladimir Dyuzhev    schedule 11.11.2008