Uploaded image for project: 'XWiki Platform'
  1. XWiki Platform
  2. XWIKI-16779

HibernateStore.saveXWikiDoc() fails but the document cache continues returning updated document

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical
    • Resolution: Fixed
    • Affects Version/s: 11.3.5
    • Fix Version/s: 11.9, 10.11.10, 11.3.6
    • Component/s: Old Core
    • Labels:
      None
    • Environment:
      XWiki 11.3.5, Jetty, HSQLDB
    • Tests:
      Unit
    • Difficulty:
      Unknown
    • Documentation:
      N/A
    • Documentation in Release Notes:
      N/A
    • Similar issues:

      Description

      Failure to save a document with an object with updated (some removed) properties produced the following stack trace:

      com.xpn.xwiki.XWikiException: Error number 3201 in 3: Exception while saving document xwiki:<myDocumentReference>
              at com.xpn.xwiki.store.XWikiHibernateStore.saveXWikiDoc(XWikiHibernateStore.java:706)
              at com.xpn.xwiki.store.XWikiCacheStore.saveXWikiDoc(XWikiCacheStore.java:216)
              at com.xpn.xwiki.store.XWikiCacheStore.saveXWikiDoc(XWikiCacheStore.java:206)
              at com.xpn.xwiki.XWiki.saveDocument(XWiki.java:1982)
      ...<my code stack>
              at com.xpn.xwiki.plugin.scheduler.AbstractJob.execute(AbstractJob.java:76)
              at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
              at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
      Caused by: com.xpn.xwiki.XWikiException: Error number 3212 in 3: Exception while saving property instanceStateDetails of object <referenceToPageContainingObject>
              at com.xpn.xwiki.store.XWikiHibernateStore.saveXWikiPropertyInternal(XWikiHibernateStore.java:1708)
              at com.xpn.xwiki.store.XWikiHibernateStore.saveXWikiCollection(XWikiHibernateStore.java:1316)
              at com.xpn.xwiki.store.XWikiHibernateStore.saveXWikiDoc(XWikiHibernateStore.java:678)
              ... 12 common frames omitted
      Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.xpn.xwiki.objects.StringProperty#<property><myPropertyName></myPropertyName></property>]
              at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:638)
              at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:305)
              at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
              at org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:57)
              at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
              at org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:742)
              at org.hibernate.impl.SessionImpl.update(SessionImpl.java:730)
              at org.hibernate.impl.SessionImpl.update(SessionImpl.java:722)
              at com.xpn.xwiki.store.XWikiHibernateStore.saveXWikiPropertyInternal(XWikiHibernateStore.java:1672)
              ... 14 common frames omitted
      

      The issue is that, after this exception and on first inspection, the UI was showing no problem, as if the save was successful. However, a second module that was performing a query on the DB was not seeing the previous document save, as hibernate failed to save it to the DB. Thus, it was the document cache (most likely) that was returning and displaying an updated document, even if the document save failed and the save itself was theoretically canceled (i.e. the entire save was reverted if one property save failed by throwing an exception abd bubbling it up).

      In order to try to help reproduce this, what I did to end up with the exception was to call object.removeField(fieldname) in order to remove a property value from an object, instead of calling object.safeput(fieldname, propClass.newProperty()) (i.e. I was removing the value completely instead of setting an empty value). I had forgotten we had changed this behavior relatively recently (to always store properties, even if empty in the DB).

        Attachments

          Activity

            People

            • Assignee:
              tmortagne Thomas Mortagne
              Reporter:
              enygma Eduard Moraru
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Date of First Response: