I have a problem when trying to insert an object that has a one to one relationship with my parent object. The insert fails if the parent object is detached and has a one to many collection.
I have posted full details of the error below and I can provide a full test case if required.
I have a couple of workarounds but none of them are really suitable...
1. I can reassociate the parent "grant" object with the session by executing a Session.Lock. This has to happen before I associate the new "GrantResponsibility" object.
2. If I call Session.Update on the parent "grant" object then the new "GrantResponsibility" is added through the cascade. However this performs unnecessary statements to be run and causes problems with the optimistic concurrency checks.
Regardless of whether this is expected behaviour or not, the error message is pretty confusing.
Hibernate version:
V1.0.3
Mapping documents:
<class name="Grant" table="`Grant`">
<id name="Id" type="Int32" unsaved-value="0">
<column name="GrantId" unique="true"/>
<generator class="native"/>
</id>
<one-to-one name="GrantResponsibility" class="GrantResponsibility" cascade="all-delete-orphan">
</one-to-one>
<bag name="GrantApprovals" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="GrantId"/>
<one-to-many class="GrantApproval"/>
</bag>
</class>
<class name="GrantApproval" table="GrantApproval">
<id name="Id" type="Int32" unsaved-value="0">
<column name="GrantApprovalId" unique="true"/>
<generator class="native"/>
</id>
<many-to-one name="Grant" class="Grant">
<column name="GrantId" not-null="true"/>
</many-to-one>
</class>
<class name="GrantResponsibility" table="GrantResponsibility">
<id name="Id" type="Int32" unsaved-value="0">
<column name="GrantId" unique="true"/>
<generator class="foreign">
<param name="property">Grant</param>
</generator>
</id>
<one-to-one name="Grant" class="Grant" constrained="true">
</one-to-one>
</class>
Code between sessionFactory.openSession() and session.close():
Grant grant;
ISession session = OpenSession();
grant = new Grant();
GrantApproval grantApprovalData = new GrantApproval();
grantApprovalData.Grant = grant;
grant.GrantApprovals.Add(grantApprovalData);
session.Save(grant);
session.Flush();
session.Close();
session = OpenSession();
// Insert a Grant Responsibility
GrantResponsibility grantResponsibility = new GrantResponsibility();
grantResponsibility.Grant = grant;
grant.GrantResponsibility = grantResponsibility;
session.Save(grantResponsibility);
session.Flush();
session.Close();
Full stack trace of any exception that occurs:
NHibernate.Test.NHSpecificTest.NHXXX.Fixture.InsertOneToOne : NHibernate.HibernateException : Don't dereference a collection with cascade="all-delete-orphan": NHibernate.Test.NHSpecificTest.NHXXX.Grant.GrantApprovals
at NHibernate.Impl.SessionImpl.PrepareCollectionForUpdate(PersistentCollection coll, CollectionEntry entry) in C:\Development\Microsoft\nhibernate-1.0.3.0\src\NHibernate\Impl\SessionImpl.cs:line 3753
at NHibernate.Impl.SessionImpl.UpdateReachableCollection(PersistentCollection coll, IType type, Object owner) in C:\Development\Microsoft\nhibernate-1.0.3.0\src\NHibernate\Impl\SessionImpl.cs:line 3676
at NHibernate.Impl.FlushVisitor.ProcessCollection(Object collection, PersistentCollectionType type) in C:\Development\Microsoft\nhibernate-1.0.3.0\src\NHibernate\Impl\FlushVisitor.cs:line 37
at NHibernate.Impl.AbstractVisitor.ProcessValue(Object value, IType type) in C:\Development\Microsoft\nhibernate-1.0.3.0\src\NHibernate\Impl\AbstractVisitor.cs:line 57
at NHibernate.Impl.AbstractVisitor.ProcessValues(Object[] values, IType[] types) in C:\Development\Microsoft\nhibernate-1.0.3.0\src\NHibernate\Impl\AbstractVisitor.cs:line 30
at NHibernate.Impl.SessionImpl.FlushEntity(Object obj, EntityEntry entry) in C:\Development\Microsoft\nhibernate-1.0.3.0\src\NHibernate\Impl\SessionImpl.cs:line 3276
at NHibernate.Impl.SessionImpl.FlushEntities() in C:\Development\Microsoft\nhibernate-1.0.3.0\src\NHibernate\Impl\SessionImpl.cs:line 3114
at NHibernate.Impl.SessionImpl.FlushEverything() in C:\Development\Microsoft\nhibernate-1.0.3.0\src\NHibernate\Impl\SessionImpl.cs:line 2867
at NHibernate.Impl.SessionImpl.Flush() in C:\Development\Microsoft\nhibernate-1.0.3.0\src\NHibernate\Impl\SessionImpl.cs:line 2843
Name and version of the database you are using:
Sql Server 2000
The generated SQL (show_sql=true):
N/A
Debug level Hibernate log excerpt:
Can supply if necessary