what does this error mean in nhibernate
Asked Answered
S

7

23

Out of the blue, i am getting this error when doing a number of updates using nhibernate.

Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [MyDomainObject]

there is no additional information in the error. Is there some recommended way to help identify the root issue or can someone give me a better explanation on what this error indicated or is a sympton around.

Some additional info

I looked at the object and all of the data looks fine, it has an ID, etc . .

Note this is running in a single call stack from an asp.net-mvc website so i wouldn't expect there to be any threading issues to worry about in terms of concurrency.

Simsar answered 9/12, 2010 at 23:54 Comment(1)
I got the same error. Interestingly, when I change session.SaveOrUpdate(ent) to session.Save(ent), it is solved. But I don't know why:) Edited: And I found this answer stating that setting unsaved-value=0 not to null solves problem. https://mcmap.net/q/591581/-do-i-have-to-load-get-an-entity-before-saveorupdate-in-nhibernateGeniagenial
M
14

It means that you have multiple transactions accessing the same data, thus producing concurrency issues. You should improve on your data access handling, you probably are updating data from multiple threads, syndicate the changed data into a queue first which handles all the access to the db.

Mclaren answered 9/12, 2010 at 23:58 Comment(1)
Well, different http requests to a server run in their own thread, so there still might a problem concerning that. James answer could pose the solution though, as the error might be in the mapping code as well.Mclaren
R
23

NHibernate has an object, let's call it theObject. theObject.Id has a value of 42. NHibernate notices that the object is dirty. The object's Id is different than the unsaved-value, which is zero (0) for integer primary keys. So NHibernate issues an update statement, but no rows are updated, which means that there is no row in the database for that type of object with an Id of 42. So the object has been deleted without NHibernate knowing about it. This could happen inside another transaction (e.g. you have threading issues) or if someone (or another application) deleted/altered the row using SQL directly against the database.

The other possibility is that your unsaved-value is wrong. e.g. You are using -1 to indicate an unsaved-entity, but your mapping has a unsaved-value of zero. This is unlikely as your application is generally working from the sounds of it. If the unsaved-value was wrong, you wouldn't have been able to save any entities to the database as NHibernate would have been issuing UPDATE statements when it should have been issuing INSERT.

Relevance answered 10/12, 2010 at 0:4 Comment(4)
dont think its a threading issues because its in a single call stack that i am getting this error . .Simsar
You would only ever have a single call stack. If two threads are racing to update/delete an object, one will win (no exception or call stack) and the other will lose (producing an exception with call stack). ASP.NET is inherently multi-threaded, though each request is executed under the illusion that it is the only thread running.Relevance
so would this only be an issue if there were multiple browsers trying to do updates at the same time ?? Also, updated the question to indicate that data looks fine...Simsar
This can be an issue anytime multiple requests are submitted that affect the same data. The multiple requests could be generated by multiple browsers, hitting refresh on a page, multiple AJAX requests by the same page, ... There are a lot of different ways that this can happen. I would recommend implementing some logging to track down the error.Relevance
M
14

It means that you have multiple transactions accessing the same data, thus producing concurrency issues. You should improve on your data access handling, you probably are updating data from multiple threads, syndicate the changed data into a queue first which handles all the access to the db.

Mclaren answered 9/12, 2010 at 23:58 Comment(1)
Well, different http requests to a server run in their own thread, so there still might a problem concerning that. James answer could pose the solution though, as the error might be in the mapping code as well.Mclaren
A
7

An old post, but hopefully my info will help someone. I was getting a similar error but only when persisting associations, after I had added in a new object. The error was of the form:

NHibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) [My.Entity#0]

Note the zero on the end, which is my identifier property. It should not be trying to save with key zero as I was using identity specification in SQL Server (generator class=native). I had not changed my unsaved-value in my xml so I had no idea what the problem was; for some reason NHibernate was trying to do an update using key value as 0 instead of a save (and getting the next key identity) for my new object.

In the end I found the cause was that I was initialising Version number to 1 for the new object in my constructor! Even though my identifier property was zero, for some reason NHibernate was also looking for a version property of zero as well, to identify it as an unsaved transient instance. The book "NHibernate in Action" does actually mention this on page 120, but for some reason my objects were fine when persisting with version number of 1 normally, and only failing if saving a new object through an association.

So make sure you do not set your Version value (leave as zero or null).

Ashtray answered 9/6, 2011 at 9:35 Comment(1)
Where do you set the version number?Edema
S
2

You say that your data is ok, but check if for example you are mapping the ID as self generate. I had the exact same problem, but I was sending an object with an ID different from 0.

Hope it helps!

Subphylum answered 14/4, 2015 at 12:24 Comment(0)
B
0

My problem was this:

[Bind(Include="Name")] EventType eventType

Should have been:

[Bind(Include="EventTypeId,Name")] EventType eventType

Just as other answers suggest nhibernate was using zero as the id for my entity.

Barron answered 4/12, 2014 at 18:5 Comment(0)
P
0

If you have a trigger on the table, it can be the reason. In this case, add inside it

SET ROWCOUNT 0; SET NOCOUNT ON;

Pikestaff answered 22/8, 2018 at 9:16 Comment(0)
H
0

This error happened to me in the following way:

List < Device > allDevices = new List < Device > ();
//Add Devices to the list
allDevices.Add(aDevice);
//Add allDevices  to  database //Will work fine

// allDevices.Clear(); //Should be used here
//Later  we add more devices
allDevices.Add(anotherDevice);
//Add allDevices to Database  -> We get the error
//Solution to this  
allDevices.Clear(); //Before adding new transaction with the oldData, 
Horta answered 25/4, 2022 at 8:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.