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.  [ 12 posts ] 
Author Message
 Post subject: Transaction Rollback does not reset version property
PostPosted: Mon Apr 24, 2006 11:12 pm 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Running with NHibernate 1.02, .NET Framework 2.0, SQLServer 2005

Okey, this is my problem:

1) I create an object of a class with automatic int32 increment versioning
2) At this point object.version is null
3) I open a Session
4) I start a new transaction
5) I do Session.SaveOrUpdate(object);
6) At this point object.version is 0
7) I rollback the transaction becasue of a custom business logic validation rule
6) I close the session (At this point object.version is still 0, shouldnt I be reset by the rollback to null?!)

Up to this point everything seems fine...but..
7) I modify some properties of my object
8) I open a new session
9) I start a new transaction
10) my object "is valid" (from the point of view of my custom business logic validation so I ...)
11) commit the transacion

EXCEPTION:NUnit.Corona.BusinessObjects.TestUsuario.TestCrearUsuarioInvalidoYSaveOrUpdate : Xade.BusinessObjects.FactoryOperationException : Row was updated or deleted by another transaction for Corona.BusinessObjects.Usuario instance with identifier: 35
----> NHibernate.StaleObjectStateException : Row was updated or deleted by another transaction for Corona.BusinessObjects.Usuario instance with identifier: 35


at Xade.BusinessObjects.BasePONOFactory`2.ExecuteWithResults[TCustomType](OperationEventHandler`1 operationHandler) in D:\Documents and Settings\fperedo\My Documents\Xade\Bibliotecas\fuentes\csharp\Xade.BusinessObjects\BasePONOFactory.cs:line 100
at Xade.BusinessObjects.BasePONOFactory`2.ExecuteWithoutResult(OperationEventHandler`1 operationHandler) in D:\Documents and Settings\fperedo\My Documents\Xade\Bibliotecas\fuentes\csharp\Xade.BusinessObjects\BasePONOFactory.cs:line 63
at Xade.BusinessObjects.BasePONOFactory`2.SaveOrUpdate(IList`1 ponos) in D:\Documents and Settings\fperedo\My Documents\Xade\Bibliotecas\fuentes\csharp\Xade.BusinessObjects\BasePONOFactory.cs:line 223
at Xade.BusinessObjects.BasePONOFactory`2.SaveOrUpdate(TPonoType pono) in D:\Documents and Settings\fperedo\My Documents\Xade\Bibliotecas\fuentes\csharp\Xade.BusinessObjects\BasePONOFactory.cs:line 210
at NUnit.Corona.BusinessObjects.TestUsuario.TestCrearUsuarioInvalidoYSaveOrUpdate() in D:\Documents and Settings\fperedo\My Documents\Xade\Corona\fuentes\csharp\NUnit.Corona\BusinessObjects\TestUsuario.cs:line 105
--FactoryOperationException
at NHibernate.Persister.AbstractEntityPersister.Check(Int32 rows, Object id) in D:\Documents and Settings\fperedo\My Documents\OpenSource\Nhibernate\src\NHibernate\Persister\AbstractEntityPersister.cs:line 567
at NHibernate.Persister.EntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Boolean[] includeProperty, Object oldVersion, Object obj, SqlString sqlUpdateString, ISessionImplementor session) in D:\Documents and Settings\fperedo\My Documents\OpenSource\Nhibernate\src\NHibernate\Persister\EntityPersister.cs:line 919
at NHibernate.Persister.EntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Object[] oldFields, Object oldVersion, Object obj, ISessionImplementor session) in D:\Documents and Settings\fperedo\My Documents\OpenSource\Nhibernate\src\NHibernate\Persister\EntityPersister.cs:line 838
at NHibernate.Impl.ScheduledUpdate.Execute() in D:\Documents and Settings\fperedo\My Documents\OpenSource\Nhibernate\src\NHibernate\Impl\ScheduledUpdate.cs:line 54
at NHibernate.Impl.SessionImpl.Execute(IExecutable executable) in D:\Documents and Settings\fperedo\My Documents\OpenSource\Nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 3076
at NHibernate.Impl.SessionImpl.ExecuteAll(IList list) in D:\Documents and Settings\fperedo\My Documents\OpenSource\Nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 3055
at NHibernate.Impl.SessionImpl.Execute() in D:\Documents and Settings\fperedo\My Documents\OpenSource\Nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 3007
at NHibernate.Impl.SessionImpl.Flush() in D:\Documents and Settings\fperedo\My Documents\OpenSource\Nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 2843
at NHibernate.Transaction.AdoTransaction.Commit() in D:\Documents and Settings\fperedo\My Documents\OpenSource\Nhibernate\src\NHibernate\Transaction\AdoTransaction.cs:line 141
at Xade.BusinessObjects.BasePONOFactory`2.ExecuteWithResults[TCustomType](OperationEventHandler`1 operationHandler) in D:\Documents and Settings\fperedo\My Documents\Xade\Bibliotecas\fuentes\csharp\Xade.BusinessObjects\BasePONOFactory.cs:line 90


The problem seems to be on my "second try" the "version" property is no longer null, because if I set it to null before my "second try" it saves perfectly... now, of course I could manually reset this version fields if I would only be saving an object at a time... but what do I do when I have to save a big object graph? why isnt the version automatically reset on rollback? how could I "plug myself in to the rollback" so that versions are set back?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 25, 2006 4:06 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
NHibernate doesn't rollback versions and identifiers yet (identifier being what matters in your case, not version). There's a JIRA issue requesting this feature.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 25, 2006 2:26 pm 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Hi!
I think the problem is not with the identity... because If I manually rollback the version, things work fine...
would you recommend a particular place to add the code to automatically rollback the version (and indentity)?

I am thinking about collectiong new entities with the interceptor... an setting their Version property back to null if the transaction fails... could that cause me strange troubles?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 25, 2006 6:40 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
luxspes wrote:
Hi!
I think the problem is not with the identity... because If I manually rollback the version, things work fine...

You're right, I was wrong :)

luxspes wrote:
would you recommend a particular place to add the code to automatically rollback the version (and indentity)?

Well, if possible, you should throw away the entities if a transaction fails, just let them be garbage-collected. Of course, sometimes you can't.

luxspes wrote:
I am thinking about collectiong new entities with the interceptor... an setting their Version property back to null if the transaction fails... could that cause me strange troubles?

You can't just set the version to null, you have to restore it to its original value, so you will have to also store away the original value in your interceptor.


Top
 Profile  
 
 Post subject: Re: Transaction Rollback does not reset version property
PostPosted: Tue Apr 25, 2006 8:12 pm 
Beginner
Beginner

Joined: Wed Oct 05, 2005 5:35 am
Posts: 47
Location: France
luxspes wrote:
7) I rollback the transaction becasue of a custom business logic validation rule


Our DBA would kill me if I were starting transactions before validating business rules... Lucky you :lol:


Top
 Profile  
 
 Post subject: When should a transaction be started?
PostPosted: Tue Apr 25, 2006 9:02 pm 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Hi Balagan!

I find this is a little off topic but interesting...
How do you manage to start the transaction after you validate business rules?
AFAIK in NHibernate you have to:

1) Create your object (with "new")
2) Open Session
3) Start transaction
4) "Save" object in session
5) Validate or saved or dirty objects in session
6) Commit or rollback transaction
7) Close session...


I guess you:

1) Create your object (with "new")
<-- validate here?
2) Open Session
<-- validate here?
3) Start transaction
4) "Save" object in session
5) Commit or rollback transaction
6) Close session...

how do you know which of the objects you really want to validate and wich one you want to discard? do you have your own "object context in top of the session? how do you mix (or don't mix) the validation of "to insert" and "to update" objects?
In ASP.NET you can just "drop" the invalid objects, because the info you are going to submit is somewhat embbeded in the form... but what do you do witn windowsforms applications where the form is directly databinded with your objects?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 25, 2006 9:14 pm 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Hi Sergey thanks for your answers.

Quote:
Well, if possible, you should throw away the entities if a transaction fails, just let them be garbage-collected. Of course, sometimes you can't.

Yes I know that is "standard procedure" ;) in java web based aplication with Hibernate... but with .NET specially in WindowsForms... the objects are binded directly to de UI... so, for example if I have a "create new customer" window, and the user forgot to add the "Last Name" of the customer, I do not want to validate that with UI code (because I might need to interact with the Customer object in another place and I want my "Last Name is required" rule to be enforced every time I try to save a Customer... so I do it with validation in the PONO level... and after the validation says "You need LastName" and indicates that to the UI thanks to my implementation of IDataErrorInfo in my PONO... I can not discard my object... (if I discard it the controls in my screen would go blank and I would force the user to capture everything again (Mmmm... I think we need more documentation on how to properly use NHibernate on WindowForms... and perhaps some extensions to make it easier)


Quote:
You can't just set the version to null, you have to restore it to its original value, so you will have to also store away the original value in your interceptor.


I agree... I think that since I am using and Int32 that it is automatically incremented by hibernate... perhaps all I have to do is "decrease" it (and if its value is 0 then "decrease it" into null... what do you think?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 25, 2006 11:03 pm 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Hi!
Well now this is weird....

If my object is "new" (it has never have been in any session) then I need to manually rollback the value of version (in this case, set it back to null)

BUT...

if my object is "not new" (it has already been saved in a previous session/transaction) then... I do not need to manually rollback the value of version... (the version is only incremented if the transacion is successful... now... i think that is a bug! or not? :S


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 6:37 am 
Beginner
Beginner

Joined: Wed Oct 05, 2005 5:35 am
Posts: 47
Location: France
Hi luxspes,
I don't know if I am in the mainstream of NH best practices here, but I'd try to build the object in a such a way that it can only reach NH layer if it is valid from business point of view: ideally, the object should validate itself. So a transaction rollback would be more like a non-recoverable exception.
Yeah, that means that you can't create objects with default counstructors and have to provide some factory method that would pre-load your new object with some defaults from the database.

Dunno if it would make a big difference for you to know if the object would be inserted or updated, since you'll be calling SaveOrUpdate I guess, but if it is you could have something like IsNew/IsDirty on your object (or you can always check the unsaved Id value) - yep, it sounds like a "your own object context on top of the session". Not sure if it makes sense in your case, but that's what I am trying to do :)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 26, 2006 7:14 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
Balagan wrote:
Hi luxspes,
I don't know if I am in the mainstream of NH best practices here, but I'd try to build the object in a such a way that it can only reach NH layer if it is valid from business point of view: ideally, the object should validate itself. So a transaction rollback would be more like a non-recoverable exception.
Yeah, that means that you can't create objects with default counstructors and have to provide some factory method that would pre-load your new object


How do handle situation where validating requires access to some other related objects? Are they loaded inside some other transaction? How do You gurantee that no-one has changed their state before saving the object which is validating?

Gert


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 04, 2007 11:25 am 
Beginner
Beginner

Joined: Mon Mar 26, 2007 5:47 am
Posts: 22
sergey wrote:
NHibernate doesn't rollback versions and identifiers yet (identifier being what matters in your case, not version). There's a JIRA issue requesting this feature.


Hi, is there already any news on this? Because we're facing the same problem...

Or any nice workaround?


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 28, 2008 8:22 am 
Beginner
Beginner

Joined: Mon Mar 26, 2007 5:47 am
Posts: 22
sergey wrote:
NHibernate doesn't rollback versions and identifiers yet (identifier being what matters in your case, not version). There's a JIRA issue requesting this feature.


Is it this one: http://jira.nhibernate.org:8080/jira/browse/NH-387?

I've seen this has been changed recently, but I don't understand completely this "2.0.0.Alpha2 [ 10190 ] ". does this mean this problem will be resolved in the 2.0 version?


Thanks a lot,


Pieter


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