I'm trying to map a one-to-zero relationship where the optional side of the association has to have its key generated as the foreign key of the other side of the relationship. THis is how the exisiting database code works and I have to ape this
When I try and save a DiaryAction (the one), with an associated ActionDocument (the one or zero), I get this:
org.hibernate.id.IdentifierGenerationException: null id generated for:class net.targetgroup.diary.ActionDocument
Any ideas ?
Hibernate version:
Hibernate 3 rc1
Mapping documents:
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class name="net.targetgroup.diary.ActionDocument" table="DIARYDOCUMENT">
<id name="identifier" type="integer" column="DIARYID" unsaved-value="-1">
<generator class="foreign">
<param name="property">action</param>
</generator>
</id>
<property name="name" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="DOCUMENTNAME" length="40" />
<property name="documentNumber" type="int" column="DOCUMENTNUMBER" length="9" />
<property name="numberOfCopies" type="net.targetgroup.util.datatypes.CustomIntType" column="NUMBEROFCOPIES" length="9" />
<property name="documentPath" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="SAVEDDOCID" length="128" />
<property name="documentStatus" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="STATUS" length="20" />
<one-to-one name="action" constrained="true" outer-join="auto" cascade="none" />
</class>
</hibernate-mapping>
and
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class name="net.targetgroup.diary.DiaryItem" table="DIARYITEM">
<id name="identifier" type="integer" column="DIARYID" unsaved-value="-1">
<generator class="native" />
</id>
<discriminator type="string" formula="trim(TYPE)" />
<property name="active" type="net.targetgroup.util.datatypes.CustomIntType" column="ACTIVEINACTIVEFLAG" length="1" />
<property name="amendedDate" type="java.sql.Timestamp" column="AMENDEDDATE" length="19" />
<property name="amendedUser" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="AMENDEDUSER" length="10" />
<property name="authorityLevel" type="int" column="AUTHORITYLEVEL" length="2" />
<property name="creationDate" type="java.sql.Timestamp" column="CREATIONDATE" length="19" />
<property name="creationUser" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CREATIONUSER" length="10" />
<property name="parentId" type="big_decimal" column="PARENTID" length="9" />
<property name="itemStatus" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="STATUS" length="20" />
<property name="priority" type="int" column="PRIORITY" length="2" />
<property name="itemSummary" type="java.lang.String" column="ITEMSUMMARY" length="60" />
<property name="itemType" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="TYPE" length="10" />
<property name="entityId" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="ENTITYID" length="60" />
<property name="entityType" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="ENTITYTYPE" length="10" />
<property name="notes" type="string" />
<subclass name="net.targetgroup.diary.Note" discriminator-value="NOTE"></subclass>
<subclass name="net.targetgroup.diary.LogEntry" discriminator-value="LOG"></subclass>
<subclass name="net.targetgroup.diary.Condition" discriminator-value="CONDITION">
<join table="DIARYACTION">
<key column="DIARYID">
</key>
<property name="conditionType" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CONDITIONTYPE" length="10" />
<property name="reviewDate" type="java.sql.Timestamp" column="REVIEWDATE" length="19" />
<property name="reviewUser" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="REVIEWUSER" length="10" />
<property name="completionDate" type="java.sql.Timestamp" column="COMPLETIONDATE" length="19" />
<property name="completionUser" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="COMPLETIONUSER" length="10" />
<property name="mandatory" type="net.targetgroup.util.datatypes.CustomBooleanType" column="MANDATORYFLAG" length="1" />
</join>
</subclass>
<subclass name="net.targetgroup.diary.DiaryAction" discriminator-value="ACTION">
<join table="DIARYACTION">
<key column="DIARYID">
</key>
<many-to-one name="documentRequest" column="DOCUMENT_ID" unique="true" cascade="all" outer-join="true" />
<property name="reviewDate" type="java.sql.Timestamp" column="REVIEWDATE" length="19" />
<property name="reviewUser" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="REVIEWUSER" length="10" />
<property name="completionDate" type="java.sql.Timestamp" column="COMPLETIONDATE" length="19" />
<property name="completionUser" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="COMPLETIONUSER" length="10" />
<property name="mandatory" type="net.targetgroup.util.datatypes.CustomBooleanType" column="MANDATORYFLAG" length="1" />
</join>
</subclass>
<subclass name="net.targetgroup.diary.DocumentRequest" discriminator-value="DOCUMENT">
<join table="DIARYDOCUMENT">
<key column="DIARYID">
</key>
<property name="name" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="DOCUMENTNAME" length="40" />
<property name="documentNumber" type="int" column="DOCUMENTNUMBER" length="9" />
<property name="numberOfCopies" type="net.targetgroup.util.datatypes.CustomIntType" column="NUMBEROFCOPIES" length="9" />
<property name="documentPath" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="SAVEDDOCID" length="128" />
<property name="documentStatus" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="STATUS" length="20" />
</join>
</subclass>
<subclass name="net.targetgroup.diary.TPMProcess" discriminator-value="TPMPROCESS">
<join table="DIARYPROCESS">
<key column="DIARYID">
</key>
<property name="processName" type="string" />
<property name="processIdentifier" type="int" column="PROCESSID" />
<property name="processStatus" type="net.targetgroup.util.datatypes.CustomStringTrimType" />
</join>
</subclass>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
getHibernateTemplate().saveOrUpdate(diaryItem); // this is Spring
Full stack trace of any exception that occurs:
2005-04-14 09:37:00,342 [main] DEBUG org.hibernate.impl.SessionImpl - opened session
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - transient instance of: net.targetgroup.diary.DiaryAction
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - saving transient instance
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - generated identifier: , using strategy: org.hibernate.id.IdentityGenerator
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - saving [net.targetgroup.diary.DiaryAction#<null>]
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - executing insertions
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - transient instance of: net.targetgroup.diary.ActionDocument
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - saving transient instance
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [net.targetgroup.diary.DiaryAction#<null>]
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - generated identifier: null, using strategy: org.hibernate.id.ForeignGenerator
org.springframework.orm.hibernate3.HibernateSystemException: null id generated for:class net.targetgroup.diary.ActionDocument; nested exception is org.hibernate.id.IdentifierGenerationException: null id generated for:class net.targetgroup.diary.ActionDocument
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.impl.SessionImpl - closing session
org.hibernate.id.IdentifierGenerationException: null id generated for:class net.targetgroup.diary.ActionDocument
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:98)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:96)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:416)
at org.hibernate.engine.Cascades$5.cascade(Cascades.java:153)
at org.hibernate.engine.Cascades.cascade(Cascades.java:721)
at org.hibernate.engine.Cascades.cascade(Cascades.java:817)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:330)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:212)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:158)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:104)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:96)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:416)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:411)
Name and version of the database you are using:
DB2 for iSeries, V5R2
The generated SQL (show_sql=true):
Debug level Hibernate log excerpt:
2005-04-14 09:37:00,342 [main] DEBUG org.hibernate.impl.SessionImpl - opened session
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - transient instance of: net.targetgroup.diary.DiaryAction
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - saving transient instance
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - generated identifier: , using strategy: org.hibernate.id.IdentityGenerator
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - saving [net.targetgroup.diary.DiaryAction#<null>]
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - executing insertions
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - transient instance of: net.targetgroup.diary.ActionDocument
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - saving transient instance
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - ignoring persistent instance
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.DefaultSaveOrUpdateEventListener - object already associated with session: [net.targetgroup.diary.DiaryAction#<null>]
2005-04-14 09:37:00,358 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - generated identifier: null, using strategy: org.hibernate.id.ForeignGenerator
org.springframework.orm.hibernate3.HibernateSystemException: null id generated for:class net.targetgroup.diary.ActionDocument; nested exception is org.hibernate.id.IdentifierGenerationException: null id generated for:class net.targetgroup.diary.ActionDocument