Hi all,
I have a problem with a nullable foreign key which is not saved creating a new object.
(I'm using Hibernate 3.2.5 + HSQLDB 1.8.0.7)
If I create the element A and then the element B which has a (nullable) foreign key to A and commit the session, in the DB the element B doesn't have the reference to the element A.
I think that the problem may be that the nullable foreign key is composed by the string 'codMetaFase' that is always not null and by the string 'codAttPiano' that can be null. Also the string 'codMetaFase' is a part of the primary key of the object B and is used also in another reference to a table called TTcMetaFasi.
This is the code of a simple test:
Code:
Session session = getSession();
Transaction tx = session.beginTransaction();
// 1- Create and save object A
TSmAttPianoModelId attPianoModelId = new TSmAttPianoModelId(codMetaFase,codAttPiano);
TSmAttPianoModel attPianoModel = new TSmAttPianoModel(attPianoModelId, ap.getTTcMetaFasi(), codAttPiano);
session.save(attPianoModel);
session.flush();
// 2- Create and save object B with the reference to object A
TSmAttStimaModelId attStimaModelId = new TSmAttStimaModelId(codMetaFase,codAttStima);
TSmAttStimaModel attStimaModel = new TSmAttStimaModel(attStimaModelId, as.getTTcMetaFasi(), attPianoModel);
session.save(attStimaModel);
session.flush();
// >>> B has the correct reference to A <<<
// 3- REFRESH
System.out.println("Dopo refresh: ");
session.refresh(attStimaModel);
// >>> B doesn't have the reference to A, the foreign key is set to null!!! <<<
tx.commit();
session.close();
From the mapping files I removed all the unnecessary properties and left only the foreign key to another table that may cause the problem.
This is the TSmAttPianoModel.hbm.xml of object A:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 7-dic-2006 10.54.29 by Hibernate Tools 3.2.0.beta8 -->
<hibernate-mapping>
<class name="it.eng.cmm.stime.model.TSmAttPianoModel" table="T_SM_ATT_PIANO_MODEL">
<composite-id name="id" class="it.eng.cmm.stime.model.TSmAttPianoModelId">
<key-property name="codMetaFase" type="string">
<column name="COD_META_FASE" length="4" />
</key-property>
<key-property name="codAttPiano" type="string">
<column name="COD_ATT_PIANO" length="20" />
</key-property>
</composite-id>
<many-to-one name="TTcMetaFasi" class="it.eng.cmm.stime.model.TTcMetaFasi" update="false" insert="false" fetch="select">
<column name="COD_META_FASE" length="4" not-null="true" />
</many-to-one>
<set name="TSmAttStimaModels" inverse="true">
<key>
<column name="COD_META_FASE" length="4" not-null="true" />
<column name="COD_ATT_PIANO" length="20" />
</key>
<one-to-many class="it.eng.cmm.stime.model.TSmAttStimaModel" />
</set>
</class>
</hibernate-mapping>
And this is the TSmAttStimaModel.hbm.xml of object B
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 7-dic-2006 10.54.29 by Hibernate Tools 3.2.0.beta8 -->
<hibernate-mapping>
<class name="it.eng.cmm.stime.model.TSmAttStimaModel" table="T_SM_ATT_STIMA_MODEL">
<composite-id name="id" class="it.eng.cmm.stime.model.TSmAttStimaModelId">
<key-property name="codMetaFase" type="string">
<column name="COD_META_FASE" length="4" />
</key-property>
<key-property name="codAttStima" type="string">
<column name="COD_ATT_STIMA" length="20" />
</key-property>
</composite-id>
<many-to-one name="TTcMetaFasi" class="it.eng.cmm.stime.model.TTcMetaFasi" update="false" insert="false" fetch="select">
<column name="COD_META_FASE" length="4" not-null="true" />
</many-to-one>
<many-to-one name="TSmAttPianoModel" class="it.eng.cmm.stime.model.TSmAttPianoModel" update="false" insert="false" fetch="select">
<column name="COD_META_FASE" length="4" not-null="true" />
<column name="COD_ATT_PIANO" length="20" />
</many-to-one>
</class>
</hibernate-mapping>
I tried many solution and all worked well if I make a reference from B to A where A is an object which is yet in the DB and not an object that I have to save.
As a workaround I removed the reference in the hibernate files using the FK as a normal property but I hope you have a better solution!!
Thank for any help,
Luca