[xwiki-users] row was deleted by another transaction
Hello XWiki experts, with our XWiki 1.5 I encounter the following complaint at trying to save the document of a user, even after a restart of the servlet container:
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.xpn.xwiki.objects.StringProperty#<?xml version="1.0" encoding="UTF-8"?> <eduLevelFine></eduLevelFine> ] at org .hibernate .persister .entity.AbstractEntityPersister.check(AbstractEntityPersister.java: 1765)
I am puzzled and have no idea where to go except into SQL, which is not really a safe thing. thanks for hints. paul
On 03/05/2010 11:50 PM, Paul Libbrecht wrote:
Hello XWiki experts,
with our XWiki 1.5 I encounter the following complaint at trying to save the document of a user, even after a restart of the servlet container:
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.xpn.xwiki.objects.StringProperty#<?xml version="1.0" encoding="UTF-8"?> <eduLevelFine></eduLevelFine> ] at org .hibernate .persister .entity.AbstractEntityPersister.check(AbstractEntityPersister.java: 1765)
I am puzzled and have no idea where to go except into SQL, which is not really a safe thing.
But I'm afraid it's the only real solution... -- Sergiu Dumitriu http://purl.org/net/sergiu/
Does it mean that any transaction might actually live in the DB for a long long time, beyond restarts of xwiki or the DB, and that a global rollback? paul Le 06-mars-10 à 00:21, Sergiu Dumitriu a écrit :
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.xpn.xwiki.objects.StringProperty#<?xml version="1.0" encoding="UTF-8"?> <eduLevelFine></eduLevelFine> ] at org .hibernate .persister .entity.AbstractEntityPersister.check(AbstractEntityPersister.java: 1765)
I am puzzled and have no idea where to go except into SQL, which is not really a safe thing.
But I'm afraid it's the only real solution...
On 03/15/2010 09:18 PM, Paul Libbrecht wrote:
Does it mean that any transaction might actually live in the DB for a long long time, beyond restarts of xwiki or the DB, and that a global rollback?
=== The context === Object properties can have different logical types: StringClass, BooleanClass, NumberClass, DBListClass, etc. This is the type that is defined in the Class, and which specifies how values are presented to the user (text input, radio boxes, textarea...). They can also have different storage types: StringProperty, LargeStringProperty, StringListProperty, IntegerProperty, LongProperty, DateProperty, etc. This is the type that is stored in the database, and which determines the column type and length. There is no 1-1 relation between logical and storage types; depending on the settings, one logical type can have up to four different storage types, and different logical types can have the same storage type. For example, the NumberClass, depending on the number type, can be stored as one of: IntegerProperty, LongProperty, FloatProperty, DoubleProperty. Another example, StaticListClass, DBListClass and DBTreeListClass, which have configurable multipleSelect and relationalStorage, can be stored as: - MS=1 and RS=1 => DBStringListProperty - MS=1 and RS=0 => StringListProperty - MS=0 => StringProperty === The problem === The problem is that the storage type for a property can be changed dynamically, by changing its settings. Thus, a Number property that used to be stored as a Float can become a Double. This means that the table that stores this type of properties will change. But since this is a weak type information, and the change happens outside Hibernate, existing properties won't get moved from one table to the other. Now, Hibernate is a little tricky, it normally doesn't expect this kind of change, so it doesn't automatically detect that an entity moved between tables. Yet, since in our mapping all properties are declared as subclasses of a generic BaseProperty, a FloatProperty and its corresponding DoubleProperty have the same identifier. So, the process that causes problems is: - Create a class with a Number property of type float - Create an object for that class - Change the property type to double - Update the existing object (the same thing for other type of changes) Internally, Hibernate does this: - Load Entity XYZ as a FloatProperty - Store Entity XYZ as a DoubleProperty Now, the two XYZ should be the same entity as far as Hibernate sees, since they are both BaseProperty and have the same ID. But, since the real type differs (FloatProperty vs DoubleProperty), they are two distinct entities. Also, the initial type of the property is stored in the BaseProperty table. Hibernate can't remove the FloatProperty, since the new XYZ doesn't reference in any way the old XYZ. It also can't save the new XYZ, since the stored type differs from the current type. Now, two things happen: - The FloatProperty is ghosted; you can't remove it from the database in any normal way, just a low level SQL query can remove it. - The DoubleProperty can't be saved because the FloatProperty is blocking it. The second issue prevents the property, along with its object, and along with its document, from being saved anymore. The first issue means that this problem will NEVER be fixed. Now, to answer your question, there are two storages active in a normal XWiki engine: the Hibernate storage, and the Cache storage. For performance reasons, the cache returns the real object that is stored in it. Depending on how the document is updated, the code might get the document from the cache (storage), update it, and push it back to the storage. Although the save fails, the object remains in the changed state, and a reference to it was already present in the cache. Next time the object is retrieved from the cache, the unsaved, but changed document will be returned. This happens as long as the document is still present in the cache. === The solution? === Theoretically, this bug was fixed (see http://jira.xwiki.org/jira/browse/XWIKI-299 ) by manually moving existing affected properties to the new correct type when a problematic class change occurs. Why does it continue to happen, beats me. I'll have to investigate again.
paul
Le 06-mars-10 à 00:21, Sergiu Dumitriu a écrit :
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.xpn.xwiki.objects.StringProperty#<?xml version="1.0" encoding="UTF-8"?> <eduLevelFine></eduLevelFine> ] at org .hibernate .persister .entity.AbstractEntityPersister.check(AbstractEntityPersister.java: 1765)
I am puzzled and have no idea where to go except into SQL, which is not really a safe thing.
But I'm afraid it's the only real solution...
-- Sergiu Dumitriu http://purl.org/net/sergiu/
On Mon, Mar 15, 2010 at 5:34 PM, Sergiu Dumitriu <[email protected]> wrote:
Theoretically, this bug was fixed (see http://jira.xwiki.org/jira/browse/XWIKI-299 ) by manually moving existing affected properties to the new correct type when a problematic class change occurs. Why does it continue to happen, beats me. I'll have to investigate again.
Note that the bug probably was fixed. Earlier Paul wrote:
with our XWiki 1.5 I encounter the following complaint at trying to
save the document of a user, even after a restart of the servlet container: Sergiu -- Thank you for the very interesting explanation of what's going on under the hood! Definitely added to my bookmarks. -- Niels.
On 03/17/2010 07:26 AM, Niels Mayer wrote:
On Mon, Mar 15, 2010 at 5:34 PM, Sergiu Dumitriu <[email protected] <mailto:[email protected]>> wrote:
Theoretically, this bug was fixed (see http://jira.xwiki.org/jira/browse/XWIKI-299 ) by manually moving existing affected properties to the new correct type when a problematic class change occurs. Why does it continue to happen, beats me. I'll have to investigate again.
Note that the bug probably was fixed. Earlier Paul wrote:
with our XWiki 1.5 I encounter the following complaint at trying to
Still, XWIKI-299 has a FixFor 1.3, so even 1.5 should have it.
save the document of a user, even after a restart of the servlet
container:
Sergiu -- Thank you for the very interesting explanation of what's going on under the hood! Definitely added to my bookmarks.
-- Niels.
-- Sergiu Dumitriu http://purl.org/net/sergiu/
participants (3)
-
Niels Mayer -
Paul Libbrecht -
Sergiu Dumitriu