Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentImportTest.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentImportTest.java (revision 1170104) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentImportTest.java (working copy) @@ -95,6 +95,18 @@ } catch (InvalidItemStateException e) { log.println("Ignoring expected error: " + e.toString()); log.flush(); + + // verify that a subsequent save() fails again + try { + session.save(); + // throw an exception instead of calling fail() + // so that the main thread actually gets to see it + throw new RepositoryException("should not get here"); + } + catch (InvalidItemStateException e2) { + // expected + } + session.refresh(false); } } finally { Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java (revision 1170104) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java (working copy) @@ -1093,7 +1093,6 @@ itemDestroyed(destroyed.getId(), data); data.setStatus(ItemImpl.STATUS_DESTROYED); - data.setState(null); } } Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (revision 1170104) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (working copy) @@ -408,10 +408,20 @@ try { local = changeLog.get(created.getId()); if (local != null) { - // underlying state has been permanently created - local.pull(); - local.setStatus(ItemState.STATUS_EXISTING); - cache.cache(local); + if (local.isNode() && local.getOverlayedState() != created) { + // mid-air collision of concurrent node state creation + // with same id (JCR-2272) + if (local.getStatus() == ItemState.STATUS_NEW) { + local.setStatus(ItemState.STATUS_UNDEFINED); // we need a state that is != NEW + } + } else { + if (local.getOverlayedState() == created) { + // underlying state has been permanently created + local.pull(); + local.setStatus(ItemState.STATUS_EXISTING); + cache.cache(local); + } + } } } catch (NoSuchItemStateException e) { /* ignore */ Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (revision 1170104) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (working copy) @@ -683,6 +683,16 @@ shared.deleted(state.getOverlayedState()); } for (ItemState state : local.addedStates()) { + if (state.isNode() && state.getStatus() != ItemState.STATUS_NEW) { + // another node with same id had been created + // in the meantime, probably caused by mid-air collision + // of concurrent versioning operations (JCR-2272) + String msg = state.getId() + + " has been created externally (status " + + state.getStatus() + ")"; + log.debug(msg); + throw new StaleItemStateException(msg); + } state.connect(createInstance(state)); shared.added(state.getOverlayedState()); } Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java (revision 1170104) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java (working copy) @@ -427,7 +427,9 @@ ItemState state = stateMgr.getItemState(propId); stateMgr.destroy(state); nodeState.removePropertyName(name); - nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); + if (nodeState.getStatus() != ItemState.STATUS_NEW) { + nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED); + } return true; } } catch (ItemStateException e) {