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.  [ 4 posts ] 
Author Message
 Post subject: Detached objects problem
PostPosted: Wed Aug 30, 2006 4:00 am 
Newbie

Joined: Tue Aug 29, 2006 12:06 pm
Posts: 3
Location: Kharkov, Ukraine
Hibernate version: 1.0.2

Hi!

Or web-application has a wizard. We decided to use detached objects with session-per-request approach.

At the last step of wizard NH raises exception - "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."

Wizard is too complex, so i post very simple code, that shows this problem.

ISessionFactory factory = cfg.BuildSessionFactory();
ISession sess;

// create some parent object before wizard started
sess = factory.OpenSession();
Parent p = new Parent();
sess.Save(p);
sess.Flush();
sess.Close();

// first page - load parent object and add child to it
sess = factory.OpenSession();
p = (Parent)sess.Load(typeof(Parent), p.ID);
Child c = new Child();
p.Children.Add(c);
c.Parent = p;
sess.Close();

// second page - attach parent object to new session
// change parent's properties
sess = factory.OpenSession();
sess.Update(p);
p.Data = 123;
sess.Close();

// final page - attach parent object and save
sess = factory.OpenSession();
sess.Update(p);
sess.Flush(); // exception!!!, nhibernate tries to update child object, added on 1st page, instead of insert it
sess.Close();

Classes:

public class Parent
{
private Guid _id;
public Guid ID
{
get { return _id; }
set { _id = value; }
}

private int _data;
public int Data
{
get { return _data; }
set { _data = value; }
}

private IList _children = new ArrayList();
public IList Children
{
get { return _children; }
set { _children = value; }
}
}

public class Child
{
public Child()
{
}

private Guid _id;
public Guid ID
{
get { return _id; }
set { _id = value; }
}

private Parent _parent;
public Parent Parent
{
get { return _parent; }
set { _parent = value; }
}
}

Mapping documents:

<class name="nh_test.Parent" table="dbo.Parent">

<id name="_id" column="ID" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid.comb" />
</id>

<property name="_data" column="Data" access="field" />

<bag name="_children" access="field" table="Child" cascade="all-delete-orphan" inverse="true" lazy="true">
<key column="ParentID" />
<one-to-many class="nh_test.Child"/>
</bag>

</class>

<class name="nh_test.Child" table="dbo.Child">

<id name="_id" column="ID" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid.comb" />
</id>

<many-to-one name="_parent" class="nh_test.Parent" column="ParentID" not-null="true" cascade="all" access="field" />

</class>

Name and version of the database you are using:sqlserver2000


Also, if change id generator from guid.comb to native all works fine. And if move child object insertion to 2nd step all works fine too. Maybe i missed something or doing something wrong?


Top
 Profile  
 
 Post subject: Detached objects problem
PostPosted: Wed Aug 30, 2006 12:14 pm 
Newbie

Joined: Tue Aug 29, 2006 12:06 pm
Posts: 3
Location: Kharkov, Ukraine
I spent some time in debug of NHibernate and found why NHibernate updates Child object on 3rd step, insted of insert it. NHibernate uses unsaved-value to determine object transient or already persistent.

So, on 1st step we added Child to Parent's collection.

// first page - load parent object and add child to it
sess = factory.OpenSession();
p = (Parent)sess.Load(typeof(Parent), p.ID);
Child c = new Child();
p.Children.Add(c);
c.Parent = p;
sess.Close();

Child has ID equals empty guid here.

On second step we reattach Parent object to new session. NHibernate determines that Child is transient, generates new GUID identifier and schedules Child to save.

// second page - attach parent object to new session
// change parent's properties
sess = factory.OpenSession();
sess.Update(p); //NH schedules Child to save here
sess.Close();

On 3rd step we reattach Parent object again, but now NH determines that Child already has ID, and it differs from unsaved-value, so NH schedules Child to update.

// final page - attach parent object and save
sess = factory.OpenSession();
sess.Update(p); // schedule Child to update, instead of save
sess.Flush(); // exception!!!, nhibernate tries to update child object, added on 1st page, instead of insert it
sess.Close();

But this code works well if we are using identity generator, in this case Child object remains "new" to NH, since its ID will be generated by DB at the final flush.

So, i'm little confused now. Maybe it is not NH's fall and i'm doing wrong? But code works fine, if we are using identity generator, so NH changes behaviour, depending on id-generation strategy selected, and maybe it is a bug?

Any thoughts? Maybe my investigation is incorrect?

P.S. Sorry for my english. Hope it is understandable. :)


Top
 Profile  
 
 Post subject: Re: Detached objects problem
PostPosted: Wed Aug 30, 2006 12:26 pm 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
andrewm wrote:
So, i'm little confused now. Maybe it is not NH's fall and i'm doing wrong? But code works fine, if we are using identity generator, so NH changes behaviour, depending on id-generation strategy selected, and maybe it is a bug?

Any thoughts? Maybe my investigation is incorrect?


Do You have <version> atrributes? If not, try to add them with appropriate un-saved value attribute...

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject: Re: Detached objects problem
PostPosted: Thu Aug 31, 2006 3:22 am 
Newbie

Joined: Tue Aug 29, 2006 12:06 pm
Posts: 3
Location: Kharkov, Ukraine
gert wrote:

Do You have <version> atrributes? If not, try to add them with appropriate un-saved value attribute...

Gert


I did it and it works fine now :) Thanks.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.