views:

2265

answers:

2

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?

+2  A: 

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.

JoshBerke
+2  A: 

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.

Justice
It's pretty obvious to me now. I was thinking about Int32 as a Java-style boxed reference-type Integer. Thanks.
Kevin Albrecht