Kevin Albrecht
Kevin Albrecht

Reputation: 7014

Nullable Property Causes Errors When Null in NHibernate

I have a property defined in my HBM file like this:

<property name="OwnerId" column="OwnerID" type="System.Int32" not-null="false" />

It is defined as a nullable field in the database also. If a record in the DB has the OwnerID column set to an integer, this object is correctly loaded by NHibernate. But if the record has it set to null, NHibernate bombs with seemingly random errors including:

1) Column name 'ModuleAnchorID' appears more than once in the result column list:

[SqlException (0x80131904): Column name 'ModuleAnchorID' appears more than once in the result column list.]
   System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +925466
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +800118
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +186
   System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1932
   System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +149
   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +1005
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +132
   System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +149
   System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +135
   NHibernate.Impl.NonBatchingBatcher.AddToBatch(IExpectation expectation) +35
   NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) +1055

2) not-null property references a null or transient value:

[PropertyValueException: not-null property references a null or transient value:]
   NHibernate.Impl.SessionImpl.CheckNullability(Object[] values, IEntityPersister persister, Boolean isUpdate) +224
   NHibernate.Impl.SessionImpl.FlushEntity(Object obj, EntityEntry entry) +1019
   NHibernate.Impl.SessionImpl.FlushEntities() +182
   NHibernate.Impl.SessionImpl.FlushEverything() +90
   NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet querySpaces) +64
   NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria, IList results) +217
   NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria) +42
   NHibernate.Impl.CriteriaImpl.List() +29

Is OwnerID a reserved field name that is somehow confusing NHibernate?

Upvotes: 0

Views: 6217

Answers (2)

yfeldblum
yfeldblum

Reputation: 65435

You need to set the type of property OwnerID to int? in the class definition. You can also get rid of the type attribute in the .hbm.xml since NHibernate can infer the type from reflection.

Upvotes: 2

JoshBerke
JoshBerke

Reputation: 67088

Can you change the type in your object to an Nullable (int?). OwnerId is not a reserved keyword. If you think about it how can you map a DB null to an Int32. Value objects don't support null semantics so you really need to use a nullable type.

As for the ModuleAnchorId I recommend that you turn showing sql on, and then post the sql to the nhibernate user's group on google. The nHibernate devs pay attention to that group.

Upvotes: 2

Related Questions