Jackrabbit Content Repository
  1. Jackrabbit Content Repository
  2. JCR-3173

InvalidItemStateException if accessing VersionHistory before checkin()

    Details

      Description

      A checkin operation fails during a transaction if the VersionHistory of a node is accessed previously. See the attached test case for further details.

      -------------------------------------------------------------------------------
      Test set: org.apache.jackrabbit.core.version.UserTransactionCheckinTest
      -------------------------------------------------------------------------------
      Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 4.072 sec <<< FAILURE!
      testRestoreWithXA(org.apache.jackrabbit.core.version.UserTransactionCheckinTest) Time elapsed: 3.858 sec <<< ERROR!
      javax.jcr.InvalidItemStateException: Could not find child e77834ee-244c-441f-ab94-19847c769fa4 of node 03629609-8049-46ee-9e80-279c70b3a34d
      at org.apache.jackrabbit.core.ItemManager.getDefinition(ItemManager.java:207)
      at org.apache.jackrabbit.core.ItemData.getDefinition(ItemData.java:99)
      at org.apache.jackrabbit.core.ItemManager.canRead(ItemManager.java:421)
      at org.apache.jackrabbit.core.ItemManager.createItemData(ItemManager.java:843)
      at org.apache.jackrabbit.core.ItemManager.getItemData(ItemManager.java:391)
      at org.apache.jackrabbit.core.ItemManager.getItem(ItemManager.java:328)
      at org.apache.jackrabbit.core.ItemManager.getItem(ItemManager.java:622)
      at org.apache.jackrabbit.core.SessionImpl.getNodeById(SessionImpl.java:493)
      at org.apache.jackrabbit.core.VersionManagerImpl$1.perform(VersionManagerImpl.java:123)
      at org.apache.jackrabbit.core.VersionManagerImpl$1.perform(VersionManagerImpl.java:1)
      at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:200)
      at org.apache.jackrabbit.core.VersionManagerImpl.perform(VersionManagerImpl.java:96)
      at org.apache.jackrabbit.core.VersionManagerImpl.checkin(VersionManagerImpl.java:115)
      at org.apache.jackrabbit.core.VersionManagerImpl.checkin(VersionManagerImpl.java:101)
      at org.apache.jackrabbit.core.NodeImpl.checkin(NodeImpl.java:2830)
      at org.apache.jackrabbit.core.version.UserTransactionCheckinTest.testRestoreWithXA(UserTransactionCheckinTest.java:35)

      1. UserTransactionCheckinTest.java
        1 kB
        Matthias Reischenbacher

        Issue Links

          Activity

          Hide
          Matthias Reischenbacher added a comment -

          Test case

          Show
          Matthias Reischenbacher added a comment - Test case
          Hide
          Matthias Reischenbacher added a comment - - edited

          Is there a known workaround until this issue gets fixed?

          Show
          Matthias Reischenbacher added a comment - - edited Is there a known workaround until this issue gets fixed?
          Hide
          Vitali Liubchanka added a comment - - edited

          Experience the same issue with checkout - change - checkin in one transaction.

          There is a code in ItemManager.getDefinition(NodeState state):
          ItemData parentData = getItemData(parentId, null, false);

          It was discovered that this data is retrieved from cache where it's not up-to-date. Invoke several times in debug finally retrieves correct data and operation is finished successfully.

          Show
          Vitali Liubchanka added a comment - - edited Experience the same issue with checkout - change - checkin in one transaction. There is a code in ItemManager.getDefinition(NodeState state): ItemData parentData = getItemData(parentId, null, false); It was discovered that this data is retrieved from cache where it's not up-to-date. Invoke several times in debug finally retrieves correct data and operation is finished successfully.
          Hide
          Roland Stamm added a comment -

          Same problem here when trying checkout - change - checkin in one transaction. This did work on the 1.6.x branch but every 2.x version shows this behavior so far.

          Show
          Roland Stamm added a comment - Same problem here when trying checkout - change - checkin in one transaction. This did work on the 1.6.x branch but every 2.x version shows this behavior so far.
          Hide
          Nick Tindall added a comment -

          It would be awesome if this were fixed. Does anyone have a workaround?

          Show
          Nick Tindall added a comment - It would be awesome if this were fixed. Does anyone have a workaround?
          Hide
          Matthias Reischenbacher added a comment -

          I've found a workaround. Vitali pointed me into the right direction. The ItemManager caches the VersionHistory. If the version history is read after the version history has been modified, no exception occurs, because the item state manager always returns the same instance of the internal node state (stored in the ChangeLog). If the version history is read before the modification, the item manager stores a version history instance in its cache (with its own node state). During the checkin operation the VersionHistory is copied (including its internal node state, see also InternalXAVersionManager.makeLocalCopy(InternalVersionHistoryImpl history)) and all new versions are added as children of the new NodeState object. The NodeState object of the version history inside the ItemManager is not updated, leading to the already known exceptions. The workaround consists of removing the version history from the item managers cache, before the checkin operation is executed. Luckily there is a method which does just that (although I guess it was not intended for this kind of usage). Please be aware that this is a dirty hack:

          // cast to jackrabbit impl
          SessionImpl impl = (SessionImpl)session;

          // read the version history one last time
          VersionHistoryImpl versionHistoryImpl = (VersionHistoryImpl)node.getVersionHistory();

          // and now remove it from the item managers cache
          impl.getItemManager().itemDestroyed(versionHistoryImpl.getId(), null);

          // ready for checkin
          Version version = node.checkin();

          I actually wanted to provide a Patch which fixes this behavior directly inside InternalXAVersionManager but I guess the xa version manager is not meant to manipulate item manager internals like the caching mechanism. It would be really nice if one of the jr committers could have a look at this issue, because I think there is not much to do than placing the right two lines of code at the right place.

          Show
          Matthias Reischenbacher added a comment - I've found a workaround. Vitali pointed me into the right direction. The ItemManager caches the VersionHistory. If the version history is read after the version history has been modified, no exception occurs, because the item state manager always returns the same instance of the internal node state (stored in the ChangeLog). If the version history is read before the modification, the item manager stores a version history instance in its cache (with its own node state). During the checkin operation the VersionHistory is copied (including its internal node state, see also InternalXAVersionManager.makeLocalCopy(InternalVersionHistoryImpl history)) and all new versions are added as children of the new NodeState object. The NodeState object of the version history inside the ItemManager is not updated, leading to the already known exceptions. The workaround consists of removing the version history from the item managers cache, before the checkin operation is executed. Luckily there is a method which does just that (although I guess it was not intended for this kind of usage). Please be aware that this is a dirty hack: // cast to jackrabbit impl SessionImpl impl = (SessionImpl)session; // read the version history one last time VersionHistoryImpl versionHistoryImpl = (VersionHistoryImpl)node.getVersionHistory(); // and now remove it from the item managers cache impl.getItemManager().itemDestroyed(versionHistoryImpl.getId(), null); // ready for checkin Version version = node.checkin(); I actually wanted to provide a Patch which fixes this behavior directly inside InternalXAVersionManager but I guess the xa version manager is not meant to manipulate item manager internals like the caching mechanism. It would be really nice if one of the jr committers could have a look at this issue, because I think there is not much to do than placing the right two lines of code at the right place.
          Hide
          Nick Tuckett added a comment -

          Getting the same result as Vitali and Roland mention above, using version 2.4.0.
          For my use cases, this means that transactions containing changes to versionable nodes are broken.
          The workaround works for me, but introduces undesirable dependencies on Jackrabbit implementation classes. So I wanted to add my weight to asking for a fix for this!

          Show
          Nick Tuckett added a comment - Getting the same result as Vitali and Roland mention above, using version 2.4.0. For my use cases, this means that transactions containing changes to versionable nodes are broken. The workaround works for me, but introduces undesirable dependencies on Jackrabbit implementation classes. So I wanted to add my weight to asking for a fix for this!

            People

            • Assignee:
              Unassigned
              Reporter:
              Matthias Reischenbacher
            • Votes:
              4 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

              • Created:
                Updated:

                Development