2011-01-22 6 views
5

Sto riscontrando problemi nella rimozione di un'altra entità attraverso la cascata delete-orphan Funziona quando cancello la raccolta di serie associata, ma non quando effettuo la raccolta dell'insieme Null. Lasciami spiegare in dettaglio. Il frammento di configurazione:rimuovere la raccolta con delete-orphan non funziona con assegnazione nulla? :(

<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> 

mio codice di esempio:

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. 

le seguenti opere in modo corretto, vale a dire: tutti gli elementi della raccolta sono tutti spostati dal db

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

Penso che questo funzioni come PersistSet di Hibernate è contrassegnato come dirty quando si chiama questo metodo.

Quanto segue tuttavia non funziona come sopra come vorrei/aspetterei.

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

Se ricarico la voce gatti dal db, che contiene ancora gli elementi BLA e nessuna dichiarazione di cancellazione è generato da Hibernate :(.. Perché no ?? ... o si tratta di un bug? I sto usando 3.6.0.Final.

+0

questa domanda espone alcune questioni complicate in ibernazione. +1. – hvgotcodes

risposta

2

Penso che sia perché Hibernate utilizza le proprie implementazioni di raccolta (motivo per cui i documenti dicono che DEVI dichiarare collezioni come interfacce, non implementazioni) e le implementazioni di raccolta obbediscono alla semantica del tuo transitivo impostazioni di persistenza Quindi, quando lo fai

cats.getBla().clear() 

la parte getBla() è l'implementazione della raccolta di ibernazione, che sa di rimuovere i bambini dalla sessione quando viene chiamato clear().

Quando si esegue

cats.setBla(null); 

non si è tolto la raccolta, si sono cambiati di riferimento del genitore alla raccolta a null. La collezione probabilmente esiste ancora nella sessione.

+0

Non capisco che c'è una differenza e che Hibernate sarebbe abbastanza intelligente per determinare la differenza comunque anche se il collegamento è reso nullo ... – edbras

+0

@edbas, collection.clear è * molto * diverso da parent.setCollection (nullo). In uno, dici alla collezione di fare qualcosa. Nell'altro, si modifica semplicemente un riferimento. – hvgotcodes

+0

Sì, lo capisco, ma comunque penserei che l'ibernazione sarebbe intelligente per gestire quello che .. My probleemem: ho un oggetto Categories che ha molte componenti annidate e un gruppo di raccolte di tipo (valore). Quando rimuovo un componente o una raccolta mi piacerebbe che Hibernate fosse in grado di segnalarlo e cancellare tutti i child sottostanti. Nota: io uso una tabella centrale per tutte queste raccolte, perché altrimenti ha scarso rendimento, in modo che tali raccolte di tipi di valore siano modellate in Hibernate come entità ...Ora sto cercando come "meglio" modellare questo in Hibernate senza creare strani collegamenti/bug – edbras

0

Nella versione 5 di Hibernate il problema è molto simile ma viene generata un'eccezione: "Una raccolta con cascade =" all-delete-orphan "non è più referenziata dall'istanza dell'entità proprietaria". Per affrontare che ho dovuto passare da valori nulli a collezioni vuote.

La questione di Hibernate è pubblicato qui: https://hibernate.atlassian.net/browse/HHH-9940

Problemi correlati