2011-01-22 8 views
5

Tengo problemas para eliminar otra entidad mediante la eliminación de huérfanos en cascada. Funciona cuando borro la colección de conjuntos asociados, pero no cuando hago que la colección de conjuntos sea nula Déjenme explicar detalladamente El fragmento de configuración:eliminar colección con delete-huérfano no funciona con asignación nula? :(

<class name="com.sample.CategoriesDefault" table="cats"> 
    <id name="id" column="id" type="string" length="40" access="property"> 
    <generator class="assigned" /> 
    </id> 
    <version name="version" column="objVrs" unsaved-value="negative"/> 

<set name="bla" lazy="false" cascade="all-delete-orphan" inverse="true"> 
     <key column="idCats" not-null="true"/> 
     <one-to-many class="com.sample.BLA"/> 
</set> 

<class name="com.sample.BLA" table="blaTEST"> 
    <id name="id" column="id" type="string" length="40" access="property"> 
    <generator class="assigned" /> 
    </id> 
    <version name="version" column="objVrs" unsaved-value="negative"/> 
    <property name="bla" type="string" column="bla"/> 
    <many-to-one name="parent" class="com.sample.CategoriesDefault" column="idCats" not-null="true"/> 
</class> 

Mi código de ejemplo:

Categories cats = new CategoriesDefault(); 
final Set<BLA> col = new HashSet<BLA>(); 
col.add(new BLA(cats)); 
cats.setBla(col); 
cats.saveOrupdate(); // will update/insert it in the db. 

las siguientes obras correctamente, es decir: todos los elementos de la colección están movidos desde la db

. 10
cats.getBla().clear(); 
cats.saveOrUpdate(); 

Creo que esto funciona porque el PersistSet de Hibernate está marcado como sucio al llamar a este método.

Lo siguiente, sin embargo, no funciona igual que el anterior como me gustaría/esperaba.

cats.setBla(null); 
cats.saveOrUpdate(); 

Si vuelvo a cargar el elemento gatos de la db, todavía contiene los artículos BLA y ninguna instrucción de eliminación es generado por Hibernate :(.. Por qué no ?? ... o se trata de un error? I estoy usando 3.6.0.Final.

+0

esta pregunta expone algunos problemas complicados en hibernación. +1. – hvgotcodes

Respuesta

2

Creo que es porque hibernate usa sus propias implementaciones de colección (por eso los documentos dicen que DEBES declarar colecciones como interfaces, no como implementaciones), y las implementaciones de colección obedecen a la semántica de tu transitivo configuración de persistencia. Por lo tanto, cuando lo haga

cats.getBla().clear() 

la parte getBla() es la implementación de la colección hibernate, que sabe cómo eliminar los elementos secundarios de la sesión cuando se invoca clear().

Al hacer

cats.setBla(null); 

no ha quitado la colección, que han cambiado de referencia de los padres de la colección en nulo. La colección probablemente todavía exista en la sesión.

+0

No entiendo que hay una diferencia y que Hibernate sería lo suficientemente inteligente como para determinar la diferencia de todos modos, incluso si el enlace se hace nulo .... – edbras

+0

@edbas, collection.clear es * muy * diferente que parent.setCollection (nulo). En uno, le dices a la colección que haga algo. En el otro, simplemente cambia una referencia. – hvgotcodes

+0

Sí, lo entiendo, pero aún así, creo que Hibernate sería inteligente para hacer lo que .. Mi problema: Tengo un objeto Categorías que tiene muchos componentes anidados y un grupo de colecciones (tipo de valor). Al eliminar un componente o una colección, me encantaría que Hibernate pudiera señalar eso y eliminar todos los elementos secundarios subyacentes. Nota: utilizo una tabla central para todas estas colecciones, ya que, de lo contrario, su rendimiento es bajo, por lo que estas colecciones de tipos de valores se modelan en Hibernate como entidades ...Ahora estoy buscando cómo "mejor" modelar esto en Hibernate sin crear enlaces extraños/error – edbras

0

En la versión 5 de Hibernate, el problema es muy similar pero se lanza una excepción: "Una colección con cascada =" all-delete-huérfano "ya no era referenciada por la instancia de entidad propietaria". Para abordar eso tuve que cambiar de valores nulos a colecciones vacías.

La cuestión en Hibernate está publicada aquí: https://hibernate.atlassian.net/browse/HHH-9940