Index: src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java (revision 1354517) +++ src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java (working copy) @@ -172,10 +172,11 @@ ItemId id = state.getId(); Map segment = getSegment(id); synchronized (segment) { - if (segment.containsKey(id)) { + ItemState s = segment.put(id, state); + // overwriting the same instance is OK + if (s != null && s != state) { log.warn("overwriting cached entry " + id); } - segment.put(id, state); } } Index: src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (revision 1354517) +++ src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (working copy) @@ -787,6 +787,17 @@ ISMLocking.ReadLock readLock = null; try { + // make sure new item states are present/referenced in cache + // we do this before the lock is downgraded to a read lock + // because then other threads will be able to read from + // this SISM again and potentially read an added item state + // before the ones here are put into the cache (via + // shared.persisted()). See JCR-3345 + for (ItemState state : shared.addedStates()) { + state.setStatus(ItemState.STATUS_EXISTING); + cache.cache(state); + } + // downgrade to read lock readLock = writeLock.downgrade(); writeLock = null;