Hi all,
NHibernate is generating an insert query on an entity *loaded* from the DB. The exception occurs when the session is flushed. The entity object has not been modified - only properties read from it. I am at a total loss why this is the case - I'm new to NH so please be gentle if the cause is obvious.
I've included all the relevant code & mapping files below. I realize the NH error shows a timeout - that's because another thread has locked the records; the error concerning me is the INSERT attempt.
Rest of application works fine.. Please help!
Hibernate version:
2.0 GA
Mapping documents:
Code:
**** User *****
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="User" table="Users" >
<id column="UserId" name="Id" >
<generator class="native"/>
</id>
<property name="Email"/>
<bag name="Ads" table="Ad" inverse="true" cascade="save-update">
<key column="UserId" />
<one-to-many class="Ad"/>
</bag>
</class>
</hibernate-mapping>
**** Ad *****
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Ad" table="Ad" >
<id column="AdId" name="Id">
<generator class="native"/>
</id>
<many-to-one column="UserId" name="User" class="User"/>
<property name="CreatedUTC" not-null="true"/>
<bag name="Attributes" inverse="true" cascade="all">
<key column="AdId"/>
<one-to-many class="AttributeValue"/>
</bag>
<bag name="Preferences" inverse="true" cascade="all">
<key column="AdId"/>
<one-to-many class="PreferenceValue"/>
</bag>
</class>
</hibernate-mapping>
**** Attribute Value *****
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="AttributeValue" table="AttributeValue">
<id column="AttributeValueId" name="Id">
<generator class="native"/>
</id>
<many-to-one class="Ad" column="AdId" name="Ad"/>
<property name="Value" type="String"/>
<many-to-one name="AttributeDefinition" column="AttributeDefinitionId" class="AttributeDefinition" />
</class>
</hibernate-mapping>
**** Attribute Definition *****
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="AttributeDefinition" table="AttributeDefinition">
<id column="AttributeDefinitionId" name="Id">
<generator class="native"/>
</id>
<property name="Name"/>
<property name="Target"/>
<property name="ValueType" column="ValueTypeId" type="Int32"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
IUser user;
try
{
NHibernateSessionManager.Instance.BeginTransaction(IsolationLevel.ReadUncommitted);
NHibernateSessionManager.Instance.GetSession().FlushMode = FlushMode.Never;
user = _session.Get<User>(UserId);
LoadForDisconnectedAccess(user);
}
finally
{
NHibernateSessionManager.Instance.RollbackTransaction(); // !! Exception !!
NHibernateSessionManager.Instance.CloseSession();
}
private void LoadForDisconnectedAccess(IUser user)
{
object o;
foreach (IAd ad in user.Ads)
{
foreach (IPreferenceValue pv in ad.Preferences)
o = pv.PreferenceDefinition.Name;
foreach (IAttributeValue av in ad.Attributes)
o = av.AttributeDefinition.Name;
}
}
Full stack trace of any exception that occurs:Code:
NHibernate.Exceptions.GenericADOException was unhandled
Message="could not update: [Rental.Data.PreferenceDefinition#76][SQL: UPDATE PreferenceDefinition SET Name = ?, Target = ?, ValueTypeId = ? WHERE PreferenceDefinitionId = ?]"
Source="NHibernate"
StackTrace:
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session)
at NHibernate.Action.EntityUpdateAction.Execute()
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
at NHibernate.Impl.SessionImpl.Flush()
at Rental.Common.NHibernateSessionManager.RollbackTransaction() in H:\ITSoftware\Development\flatmates\trunk\Core\Rental.Common\NHibernateSessionManager.cs:line 174
at Rental.Biz.CompatabilityEngine.Engine.Execute() in H:\ITSoftware\Development\flatmates\trunk\Core\Rental.Biz\CompatabilityEngine\Engine.cs:line 173
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Data.SqlClient.SqlException
Message="Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.\r\nThe statement has been terminated."
Source=".Net SqlClient Data Provider"
ErrorCode=-2146232060
Class=11
LineNumber=0
Number=-2
Procedure=""
Server=".\\SQLEXPRESS"
State=0
StackTrace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation)
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
InnerException:
Name and version of the database you are using:
MSSQL Express 2005
The generated SQL (show_sql=true):
Debug level Hibernate log excerpt: