Hi,
from the following pages, I got the impression that Hibernate 3 now supports bi-directional one-to-many associations using Lists by setting inverse="false" on the parent and mapping the list index as a read-only property of the child:
http://www.hibernate.org/193.html
http://www.hibernate.org/116.html#A9
I try to use this with cascade="all-delete-orphan" declared on the parent's list property. This does eventually result in the deletion of a child if I call parent.getChildren().remove(), but first Hibernate tries to decouple the child from the parent by setting the foreign key and list index to null.
Since this is a real parent/child relation, I have defined a non-null constraint on these columns so this causes an error. If I remove the constraint the delete will take place, but only after a useless update of a row that is to be deleted anyway.
I cannot find more documentation on if and if so, how this is supported and if it is supposed to work this way. Can anyone shed some light on this issue? Is the mapping using inverse="false" as described on the given pages the recommended way to use a bi-directional list-association in Hibernate 3, or should I resort to doing my own list index management and use a set mapping instead?
Hibernate version: 3.0.5
Mapping documents:
parent (only subclass shown; the where-clause is needed because there are other associations to other subclasses in the same table as explained here):
Code:
<subclass name="Control" extends="Category" discriminator-value="CO">
<!-- bi-directional list assocation, so no inverse -->
<list name="controlItems" cascade="all-delete-orphan" where="T930_ITM_TYPE='CI'">
<key column="T930_CAT_UUID"/>
<index column="T930_ITM_LIST_INDEX"/>
<one-to-many class="ControlItem" />
</list>
</subclass>
child (both super- and subclass mappings):Code:
<class name="Item" table="TB930_ITM" abstract="true" discriminator-value="null">
<id name="id" unsaved-value="none">
<column name="T930_ITM_UUID" not-null="true" sql-type="char(32)" />
<generator class="assigned" />
</id>
<discriminator column="T930_ITM_TYPE" type="string" length="2" />
<version name="serverVersion" type="int" column="T930_ITM_VERSION" access="property" unsaved-value="negative" />
<!-- skipping some simple properties... -->
<!-- read-only property used by Hibernate
to manage bi-directional List associations
from Category subclasses -->
<property name="listIndex" column="T930_ITM_LIST_INDEX" type="int" update="false" not-null="true"/>
</class>
...and the subclass for the child:Code:
<subclass name="ControlItem" extends="Item" discriminator-value="CI">
<many-to-one name="control">
<column name="T930_CAT_UUID" not-null="true" sql-type="char(32)" />
</many-to-one>
</subclass>
The generated SQL on removal of the single ControlItem of a Control:Code:
2005-06-06 09:03:18,224 DEBUG [main] org.hibernate.SQL - update TB920_CAT set T920_CAT_VERSION=?, T920_CAT_NAME_PRI=?, T920_CAT_NAME_SEC=?, T920_CAT_GUIDE_REF=?, T920_CAT_EFF_START=?, T920_CAT_EFF_END=?, T920_CAT_LAST_MUTATED=?, T920_CAT_LAST_MUTATED_BY=? where T920_CAT_UUID=? and T920_CAT_VERSION=?
2005-06-06 09:03:18,646 DEBUG [main] org.hibernate.SQL - update TB930_ITM set T930_CAT_UUID=null, T930_ITM_LIST_INDEX=null where T930_CAT_UUID=? and T930_ITM_TYPE='CI'
2005-06-06 09:03:18,693 DEBUG [main] org.hibernate.SQL - delete from TB930_ITM where T930_ITM_UUID=? and T930_ITM_VERSION=?
The first statement updates the version of the parent and the third removes the child, but I don't understand why Hibernate insists on calling the second statement if the row (yes, it is the same row, I checked the SQL bindings) is to be deleted.
When removing a child from a collection with multiple items the behaviour is the same: always an extra update nulling out the foreign key and list index before the delete in the same session/transaction.
Thanks in advance for any help on this subject.
Joris[/url]