Greetings,
nullifyTransientReferences problem. I understand I am having this problem with NHibernate but the issue seems to be sufficiently "core" that I would post here on the offchance one of the core developers have spotted it. Had developers go through the 10+ 'in action' books we purchased, debugged, googled etc etc.
The issue is persisting a multi-tenant data model such as this, where every object is associated with a company.
Code:
class Company {
Address mainAddress; // Nullable FK
// ...
}
class Address {
Company company; // NOT-NULL FK
// ...
}
I create a company, assign a main address and saveOrUpdate the company. nullifyTransientReferences nulls out the company in the Address instance, which then subsequently fails with the "not null property references a null or transient value."
It seems as though the 'nullification for constraints' only works if the constraints go in the same direction as the hierarchy being persisted.
Is this issue familiar to anyone in the core Hib team? From code inspection it seems Hib 3 approaches things the same way - does anyone know if it has been fixed? Or am I just being stupid here, in which case feel free to clobber me on the head (a previous e-mail from someone else on this subject really annoyed Gavin)
Hibernate version:
NHibernate 2.x
Mapping documents:
<class name="Core.Domain.Company" table="Tenant" lazy="true">
<id name="Id" column="Id" type="Int64" unsaved-value="-1">
<generator class="ORM.IdentifierGenerator">
<param name="lo">10</param>
</generator>
</id>
<many-to-one name="MainAddress" column="MainAddress_Id" class="Core.Domain.Address" cascade="save-update" />
</class>
<class name="Core.Domain.Address" table="Address" lazy="true" >
<id name="Id" column="Id" type="Int64" unsaved-value="-1">
<generator class="ORM.IdentifierGenerator">
<param name="lo">10</param>
</generator>
</id>
<property name="Street1" column="Street1" type="String" length="128" not-null="false" />
<property name="Street2" column="Street2" type="String" length="128" not-null="false" />
<property name="City" column="City" type="String" length="64" not-null="false" />
<property name="State" column="State" type="String" length="64" not-null="false" />
<property name="Zip" column="Zip" type="String" length="64" not-null="false" />
<many-to-one name="AffiliatedTenant" column="Tenant_Id" class="Core.Domain.Company" not-null="true" cascade="none" />
</class>
Full stack trace of any exception that occurs:
DETAILS: Bug: Caught non-goose exception at top level! ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> NHibernate.PropertyValueException: not-null property references a null or transient value: Everdream.Core.Domain.Address.AffiliatedTenant
at NHibernate.Impl.SessionImpl.CheckNullability(Object[] values, IEntityPersister persister, Boolean isUpdate) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1401
at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 954
at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 872
at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 767
at NHibernate.Impl.SessionImpl.Save(Object obj) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 708
at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1543
at NHibernate.Engine.Cascades.CascadingAction.ActionSaveUpdateClass.Cascade(ISessionImplementor session, Object child, Object anything) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 172
at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 562
at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IEntityPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 643
at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 901
at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 872
at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 767
at NHibernate.Impl.SessionImpl.Save(Object obj) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 708
at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj) in C:\home\neil\everdream\perforce\dev\mainline\goose\3rdparty\NHibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1543
at Everdream.Core.Session.TrackedHibernateSession.SaveOrUpdate(Object obj) in C:\home\neil\everdream\perforce\dev\mainline\goose\appserver\src\Everdream.Core\Session\TrackedHibernateSession.cs:line 153
at Everdream.Core.DAO.DomainObjectDAO`1.MakePersistent(T obj) in C:\home\neil\everdream\perforce\dev\mainline\goose\appserver\src\Everdream.Core\DAO\AbstractDomainObjectDAO.cs:line 89
Name and version of the database you are using:
SQL Server 2005 with constraints