Hi all,
I have a ternary relationship between classes A,B,C and the intermediate table D, that contains the three identifiers for classes A,B,C.
From class A, I mapped the related objects BC by using a composite-element.
...
<class name="core.A" table="T_A">
...
<set name="importantPersons" table="T_D" cascade="all" inverse="false" lazy="false">
<key column="IDA"/>
<composite-element class="core.BC">
<many-to-one name="b" column="IDB" class="core.B" cascade="none"/>
<many-to-one name="c" column="IDC" class="core.C" cascade="save-update"/>
</composite-element>
</set>
...
</class>
...
For class B and C I have a proper hbm.xml mapping file (easy)
1. Do I need a hbm.xml mapping file for the BC class? Because I just created a java class BC that contains two properties, proprertie B and propertie C + getters/setters (so it just represents the relationship BC). Currently, I also have mapped the object BC with the BC.hbm.xml file, but I think this is not needed because I don't need the relationship BC as such in hibernate. I just need the software object BC to relate B to C, but a BC as such should not be persisted. B and C should be separately persisted.
2. I load an A and B object from the db. Next I create a new C object (id = -1, which is the 'unsaved-value' for this class (declaredin C.hbm.xml))
I create a new BC object and I set the two properties b and c to B and C (the ones I created/loaded). Then I attach this BC object to the main A object. Then I try
...
Session session = SessionFactory.openSession();
Transaction tr = session.getTransaction();
session.update(A);
tr.commit();
session.close();
...
But I get an error that
net.sf.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: core.C
at net.sf.hibernate.impl.SessionImpl.throwTransientObjectException(SessionImpl.java:2734)
at net.sf.hibernate.impl.SessionImpl.getEntityIdentifierIfNotUnsaved(SessionImpl.java:2726)
at net.sf.hibernate.type.EntityType.getIdentifier(EntityType.java:66)
at net.sf.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:46)
at net.sf.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:154)
at net.sf.hibernate.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:384)
at net.sf.hibernate.collection.Set.writeTo(Set.java:227)
at net.sf.hibernate.collection.AbstractCollectionPersister.insertRows(AbstractCollectionPersister.java:621)
at net.sf.hibernate.impl.ScheduledCollectionUpdate.execute(ScheduledCollectionUpdate.java:49)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2382)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2338)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2204)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
So hibernate cannot find the reference to object C, the one I just created... Because in the mapping file, I evevywhere use a cascade attribute, I thought that Hibernate would cascade the update of A, then come to object C, detects that the unsaved value = -1 == identifier and so, does an insert on object C, but this doesn't work.
Anyone any idea how I can solve this problem? (without first saving the object C myself, because I thought that hibernate was powerfull enough to detect the relationships/ persisted/not yet persisted objects so that it could do it for me)
Is my question at 1. related to the problem in 2. ? I was already familiar with the basic mappings in hibernate, but now, I touch a ternary relationship which causes me problems. Any help would be of great help to master this part too!
Jeroen Christiaens
<see also topic
http://forum.hibernate.org/viewtopic.php?t=929608>