Hibernate version:
3.0
Mapping documents:
<hibernate-mapping auto-import="false">
-
<class name="Model" table="Model">
<id name="modelID" type="long" column="modelID" unsaved-value="0">
<generator class="native"/>
</id>
<bag name="aggs" inverse="true" cascade="all">
<key column="aggby_Model"/>
<one-to-many class="Element"/>
</bag>
</class>
<class name="Element" table="Element">
<id name="elementID" type="long" column="elementID" unsaved-value="0">
<generator class="native"/>
</id>
<many-to-one name="aggby" class="Model">
<column name="aggby_Model" not-null="true"/>
</many-to-one>
<joined-subclass name="Warehouse" extends="Element" table="Warehouse">
<key column="elementID"/>
<bag name="shipsTo" inverse="true">
<key column="suppliedBy_Warehouse"/>
<one-to-many class="PostCode"/>
</bag>
</joined-subclass>
<joined-subclass name="PostCode" extends="Element" table="PostCode">
<key column="elementID"/>
<many-to-one name="suppliedBy" class="Warehouse" >
<column name="suppliedBy_Warehouse" not-null="true"/>
</many-to-one>
<property name="code" type="string">
<column name="code" unique="true" not-null="true" length="10"/>
</property>
</joined-subclass>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
Transaction trx = session.beginTransaction();
Model model = new Model( );
session.save( model );
PostCode pCode = new PostCode( );
pCode.setCode("55555");
model.getAggs().add(pCode);
Warehouse wHouse = new Warehouse( );
model.getAggs().add(wHouse);
pCode.setSuppliedBy(wHouse);
trx.commit();
Full stack trace of any exception that occurs:
N/A
Name and version of the database you are using:
Oracle 10G
The generated SQL (show_sql=true):
N/A
Debug level Hibernate log excerpt:
N/A
I assume hibernate goes through the persistent collection ( "aggs" in the example above ) and tries to persist it by the order it has been populated. Since PostCode instance is added into the collection first , it is being processed before the Warehouse instance. There is a not-null constraint on the suppliedBy_Warehouse relationship from PostCode to Warehouse. While PostCode instance is being processed , hibernate nullifies the suppliedBy_Warehouse field. I think the reason is that Warehouse object is still transient ( detached ). And I got,
net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: PostCode.suppliedBy .
I solved this problem by changing the mapping for the PostCode as follows :
...
<joined-subclass name="PostCode" extends="Element" table="PostCode">
<key column="elementID"/>
-
<many-to-one name="suppliedBy" class="Warehouse" cascade="save-update">
<column name="suppliedBy_Warehouse" not-null="true"/>
</many-to-one>
-
<property name="code" type="string">
<column name="code" unique="true" not-null="true" length="10"/>
</property>
</joined-subclass>
...
My concern is that if there is a cycle in the object graph, hibernate will go in an infinite loop while cascading. Please advise...
Thanks,
Bora
|