-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Problem updating children which get hidden by a View
PostPosted: Wed May 31, 2006 1:10 am 
Beginner
Beginner

Joined: Mon Nov 21, 2005 6:38 pm
Posts: 30
Location: New Zealand
Hi,

I am using NHibernate over a SQL Server database view rather than working directly with the underlying table. The view simply excludes objects that have their IsDeleted property set to true.

My problem arises when I update a parent object where one of the changes is that a child's IsDeleted property is now True.

It appears that NHibernate is checking whether the row was updated by looking at the affected row count but the row has been hidden by the view and so the row count comes back as 0.

Does anyuone have any suggestions on how I can get NHibernate to work over the view?

Interestingly enough, if the parent object is changed so that its IsDeleted property becomes True, then NH doesn't throw an exception.

BTW, having the view is non-negotiable.

Thanks,
Dean.

NHibernate version:
1.0.1

Code between sessionFactory.openSession() and session.close():

ISession hibernateSession = CreateHibernateSession();

IList outArray = new ArrayList();

ITransaction t = null;

try
{
t = hibernateSession.BeginTransaction();

foreach (IDomainObject domObj in objectList)
{
hibernateSession.SaveOrUpdate(domObj);
}

t.Commit();
}

Full stack trace of any exception that occurs:

NHibernate.Impl.SessionImpl [(null)] - could not synchronize database state with session
NHibernate.HibernateException: SQL insert, update or delete failed (expected affected row count: 1, actual affected row count: 0). Possible causes: the row was modified or deleted by another user, or a trigger is reporting misleading row count.
at NHibernate.Impl.NonBatchingBatcher.AddToBatch(Int32 expectedRowCount)
at NHibernate.Collection.AbstractCollectionPersister.Recreate(PersistentCollection collection, Object id, ISessionImplementor session)
at NHibernate.Impl.ScheduledCollectionRecreate.Execute()
at NHibernate.Impl.SessionImpl.Execute(IExecutable executable)
at NHibernate.Impl.SessionImpl.ExecuteAll(IList list)
at NHibernate.Impl.SessionImpl.Execute()

Name and version of the database you are using:
SQLServer 2000

The generated SQL (show_sql=true):
not available

Debug level Hibernate log excerpt:

Mapping documents:

NHibernate.HibernateException: SQL insert, update or delete failed (expected affected row count: 1, actual affected row count: 0). Possible causes: the row was modified or deleted by another user, or a trigger is reporting misleading row count.

Code:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  <class name="EAF.Domain.Model.Definition, EAF.Domain.Model" table="Definition" discriminator-value="Definition">
    <meta attribute="scope-class" inherit="false">public abstract</meta>
    <id name="Id" type="EAF.Persistence.NullGuidUserType, EAF.Persistence" column="Id">
      <generator class="assigned" />
    </id>
    <discriminator column="DEFINITION_TYPE" type="string" />
    <version name="Version" column="Version" type="Int32" unsaved-value="-1" />
    <property name="_name" type="String(255)" column="Name" access="field" />
    <property name="_pluralName" type="String(2048)" column="PluralName" access="field" />
    <property name="Description" type="String(2048)" column="Description" />
    <property name="IsDeleted" type="YesNo" column="IsDeleted" />
    <list name="Components" inverse="false" lazy="false" cascade="save-update">
      <key column="ComponentsId" />
      <index column="ListIndex" />
      <one-to-many class="EAF.Domain.Model.Definition,EAF.Domain.Model" />
    </list>
  </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 31, 2006 10:41 am 
Beginner
Beginner

Joined: Tue May 17, 2005 7:25 pm
Posts: 43
Location: Somewhere, USA
You should look into INSTEAD OF triggers for SQL Server views. You may be able to control affected record count using those triggers.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 01, 2006 10:39 pm 
Beginner
Beginner

Joined: Mon Nov 21, 2005 6:38 pm
Posts: 30
Location: New Zealand
For posterity I am posting the reason why my error was occuring:

It is because my mapping is not bi-directional. So this was forcing a double update of the child row. 1 to update the properties that changed (the IsDeleted property in this case) and a 2nd to re-connect the child to the parent object
.
In this case, the db view swallowed the row after the first update and this caused the 2nd update to fail.

Unfortunately I cannot implement a two-way relationship as this can cause too many objects to be retrieved. The client app is able to work in a disconnected state, so lazy loading is not an option and retrieving everything is not feasible as NH is working on an app server and I need to minimise the amount of data that is sent to the client.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 01, 2006 10:49 pm 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
Can you add to your client API the ability to specify how much data you want to retrieve? This may solve the lazy loading vs. "always get full data set" problem. It worked for me but I don't fully understand your situation.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 01, 2006 11:40 pm 
Beginner
Beginner

Joined: Mon Nov 21, 2005 6:38 pm
Posts: 30
Location: New Zealand
Interesting concept; I will have a word to our architect and see if this is feasible. Thanks.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.