diff --git a/src/main/java/org/apache/jackrabbit/ocm/manager/cache/ObjectCache.java b/src/main/java/org/apache/jackrabbit/ocm/manager/cache/ObjectCache.java
index e450390..5ec20ce 100644
--- a/src/main/java/org/apache/jackrabbit/ocm/manager/cache/ObjectCache.java
+++ b/src/main/java/org/apache/jackrabbit/ocm/manager/cache/ObjectCache.java
@@ -16,8 +16,6 @@
  */
 package org.apache.jackrabbit.ocm.manager.cache;
 
-
-
 /**
  *
  *
@@ -26,15 +24,53 @@
  * @author <a href="mailto:christophe.lombart@gmail.com">Lombart Christophe </a>
  *
  */
-public interface ObjectCache
-{
-
-	void cache(String path, Object object);
-	
-	void clear();
-	
-	boolean isCached(String path);
-	
-	Object getObject(String path);
-	
+public interface ObjectCache {
+
+    /**
+     * Put an object to current session's object cache
+     *
+     * @param path Path to object
+     * @param object Cached object
+     */
+    void cache(String path, Object object);
+
+    /**
+     * Clear current session's object cache
+     */
+    void clear();
+
+    /**
+     * Check for object presence in the current session's object cache If the object is not in the current session's
+     * object cache, it is copied to current session's object cache from the global object cache.
+     *
+     * @param path Path to object
+     * @return true if the object is present in the current session's object cache
+     */
+    boolean isCached(String path);
+
+    /**
+     * Get the object from the current session's object cache. If the object is not in the current session's object
+     * cache, it is copied to current session's object cache from the global object cache.
+     *
+     * @param path Path to object
+     * @return Object (perhaps partially loaded), or null otherwise
+     */
+    Object getObject(String path);
+
+    /**
+     * Remove an object from the current session's object cache. Also remove the object and all its subobjects from the
+     * global object cache.
+     *
+     * @param path Path to object
+     */
+    void evict(String path);
+
+    /**
+     * Transfer a fully loaded object into the global object cache.
+     *
+     * @param path Path to object
+     * @param object A fully loaded object
+     */
+    void ready(String path, Object object);
+
 }
diff --git a/src/main/java/org/apache/jackrabbit/ocm/manager/cache/impl/RequestObjectCacheImpl.java b/src/main/java/org/apache/jackrabbit/ocm/manager/cache/impl/RequestObjectCacheImpl.java
index 390cae8..ece2b77 100644
--- a/src/main/java/org/apache/jackrabbit/ocm/manager/cache/impl/RequestObjectCacheImpl.java
+++ b/src/main/java/org/apache/jackrabbit/ocm/manager/cache/impl/RequestObjectCacheImpl.java
@@ -22,36 +22,39 @@
 import org.apache.jackrabbit.ocm.manager.cache.ObjectCache;
 
 /**
-*
-* This is a simple cache implementation that can be used per retrieve requests.
-* This avoids to load duplicated object instance.
-*
+ *
+ * This is a simple cache implementation that can be used per retrieve requests. This avoids to load duplicated object
+ * instance.
+ * 
 * @author <a href="mailto:christophe.lombart@gmail.com">Lombart Christophe </a>
-*
+ * 
 */
-public class RequestObjectCacheImpl implements ObjectCache
-{
-
-	private Map alreadyCachedObjects = new HashMap();
-	
-	public void cache(String path, Object object)
-	{		
-		alreadyCachedObjects.put(path, object);
-	}
-	
-	public void clear()
-	{
-		alreadyCachedObjects.clear();
-	}
-	
-	public boolean isCached(String path)
-	{		
-	     return alreadyCachedObjects.containsKey(path);
-	}
-	
-	public Object getObject(String path)
-	{
-		return alreadyCachedObjects.get(path);
-	}
+public class RequestObjectCacheImpl implements ObjectCache {
+
+    private final Map alreadyCachedObjects = new HashMap();
+
+    public void cache(String path, Object object) {
+        alreadyCachedObjects.put(path, object);
+    }
+
+    public void clear() {
+        alreadyCachedObjects.clear();
+    }
+
+    public boolean isCached(String path) {
+        return alreadyCachedObjects.containsKey(path);
+    }
+
+    public Object getObject(String path) {
+        return alreadyCachedObjects.get(path);
+    }
+
+    public void evict(String path) {
+        alreadyCachedObjects.remove(path);
+    }
+
+    public void ready(String path, Object object) {
+        /* noop - no global cache */
+    }
 
 }
diff --git a/src/main/java/org/apache/jackrabbit/ocm/manager/impl/ObjectContentManagerImpl.java b/src/main/java/org/apache/jackrabbit/ocm/manager/impl/ObjectContentManagerImpl.java
index 4642614..43fb42d 100644
--- a/src/main/java/org/apache/jackrabbit/ocm/manager/impl/ObjectContentManagerImpl.java
+++ b/src/main/java/org/apache/jackrabbit/ocm/manager/impl/ObjectContentManagerImpl.java
@@ -186,11 +186,14 @@ public ObjectContentManagerImpl(Session session, InputStream[] xmlMappingFiles)
      * @param converter
      *            the <code>ObjectConverter</code> to be used internally
      * @param queryManager
-     *            the query manager to used
+     *            the query manager to be used
+     * @param requestObjectCache
+     *            the request object cache to be used
      * @param session
      *            The JCR session
      */
-    public ObjectContentManagerImpl(Mapper mapper, ObjectConverter converter, QueryManager queryManager, ObjectCache requestObjectCache, Session session) {
+    public ObjectContentManagerImpl(Mapper mapper, ObjectConverter converter, QueryManager queryManager, 
+            ObjectCache requestObjectCache, Session session) {
         this.mapper = mapper;
         this.session = session;
         this.objectConverter = converter;
@@ -390,6 +393,7 @@ public void insert(Object object) {
         }
 
         objectConverter.insert(session, object);
+        requestObjectCache.ready(path, object);
     }
 
     public void update(Object object) {
@@ -405,6 +409,7 @@ public void update(Object object) {
         }
 
         objectConverter.update(session, object);
+        requestObjectCache.ready(path, object);
     }
 
     public void remove(String path) {
@@ -417,6 +422,7 @@ public void remove(String path) {
 
             Item item = session.getItem(path);
             item.remove();
+            requestObjectCache.evict(path);
 
         } catch (RepositoryException e) {
             throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to remove the object at " + path);
@@ -431,7 +437,7 @@ public void remove(Object object) {
     public void remove(Query query) {
         try {
             String jcrExpression = this.queryManager.buildJCRExpression(query);
-            log.debug("Remove Objects with expression : " + jcrExpression);
+            log.debug("Remove Objects with expression: {}", jcrExpression);
 
             // Since only nodes are sufficient for us to remove,
             // getObjects(query, language) method is not called here.
@@ -445,7 +451,7 @@ public void remove(Query query) {
                     // node has been removed possibly by another thread during iterating through the results
                     continue;
                 }
-                log.debug("Remove node : " + node.getPath());
+                log.debug("Remove node: {}", node.getPath());
 
                 // it is not possible to remove nodes from an NodeIterator
                 // So, we add the node found in a collection to remove them
@@ -456,12 +462,14 @@ public void remove(Query query) {
             // Remove all collection nodes
             for (int i = 0; i < nodes.size(); i++) {
                 Node node = (Node) nodes.get(i);
-                checkIfNodeLocked(node.getPath());
+                String path = node.getPath();
+                checkIfNodeLocked(path);
                 try {
                     node.remove();
                 } catch (javax.jcr.RepositoryException re) {
                     throw new ObjectContentManagerException("Cannot remove node at path " + node.getPath() + " returned from query " + jcrExpression, re);
                 }
+                requestObjectCache.evict(path);
             }
 
         } catch (InvalidQueryException iqe) {
@@ -567,7 +575,7 @@ public Collection getObjects(Class objectClass, String path) throws ObjectConten
 
     public Iterator getObjectIterator(Query query) {
         String jcrExpression = this.queryManager.buildJCRExpression(query);
-        log.debug("Get Object with expression : " + jcrExpression);
+        log.debug("Get Object with expression: {}", jcrExpression);
         @SuppressWarnings("deprecation")
         NodeIterator nodeIterator = getNodeIterator(jcrExpression, javax.jcr.query.Query.XPATH);
 
@@ -576,7 +584,7 @@ public Iterator getObjectIterator(Query query) {
     }
 
     public Iterator getObjectIterator(String query, String language) {
-        log.debug("Get Object with expression : " + query);
+        log.debug("Get Object with expression: {}", query);
         NodeIterator nodeIterator = getNodeIterator(query, language);
 
         return new ObjectIterator(nodeIterator, this.objectConverter, this.session);
@@ -584,14 +592,14 @@ public Iterator getObjectIterator(String query, String language) {
 
     public Collection getObjects(String query, String language) {
         try {
-            log.debug("Get Objects with expression : " + query + " and language " + language);
+            log.debug("Get Objects with expression [{}] and language {}", query, language);
 
             NodeIterator nodeIterator = getNodeIterator(query, language);
 
             List result = new ArrayList();
             while (nodeIterator.hasNext()) {
                 Node node = nodeIterator.nextNode();
-                log.debug("Node found : " + node.getPath());
+                log.debug("Node found: {}", node.getPath());
                 result.add(objectConverter.getObject(session, node.getPath()));
             }
             requestObjectCache.clear();
@@ -604,9 +612,7 @@ public Collection getObjects(String query, String language) {
     }
 
     private NodeIterator getNodeIterator(String query, String language) {
-        if (log.isDebugEnabled()) {
-            log.debug("Get Node Iterator with expression " + query + " and language " + language);
-        }
+        log.debug("Get Node Iterator with expression [{}] and language {}", query, language);
         javax.jcr.query.Query jcrQuery;
         try {
             jcrQuery = session.getWorkspace().getQueryManager().createQuery(query, language);
@@ -1120,7 +1126,9 @@ private void copy(Node srcNode, Node destNode) throws RepositoryException {
             Node node = iter.nextNode();
             Node child;
             // check if the subnode is autocreated
-            if (!node.getDefinition().isAutoCreated() && destNode.hasNode(node.getName())) {
+            if (!node.getDefinition().isAutoCreated() 
+                    && node.getIndex()==1
+                    && destNode.hasNode(node.getName())) {
                 child = destNode.getNode(node.getName());
             } else {
                 child = destNode.addNode(node.getName(), node.getPrimaryNodeType().getName());
diff --git a/src/main/java/org/apache/jackrabbit/ocm/manager/objectconverter/impl/ObjectConverterImpl.java b/src/main/java/org/apache/jackrabbit/ocm/manager/objectconverter/impl/ObjectConverterImpl.java
index 15d4e4f..212a0bd 100644
--- a/src/main/java/org/apache/jackrabbit/ocm/manager/objectconverter/impl/ObjectConverterImpl.java
+++ b/src/main/java/org/apache/jackrabbit/ocm/manager/objectconverter/impl/ObjectConverterImpl.java
@@ -360,6 +360,8 @@ public Object getObject(Session session, String path) {
 			retrieveBeanFields(session, classDescriptor, node, object, false);
 			retrieveCollectionFields(session, classDescriptor, node, object, false);
 
+            requestObjectCache.ready(path, object);
+
 			return object;
 
 		} catch (PathNotFoundException pnfe) {
@@ -444,6 +446,8 @@ public Object getObject(Session session, Class clazz, String path)
 			retrieveBeanFields(session, classDescriptor, node, object, false);
 			retrieveCollectionFields(session, classDescriptor, node, object, false);
 
+            requestObjectCache.ready(path, object);
+
 			return object;
 		} catch (PathNotFoundException pnfe) {
 			// HINT should never get here
@@ -709,6 +713,8 @@ private void retrieveBeanField(Session session,BeanDescriptor beanDescriptor, No
 			requestObjectCache.cache(beanPath, bean);
 			ReflectionUtils.setNestedProperty(object, beanName, bean);
 		}
+
+        requestObjectCache.ready(beanPath, bean);
 	}
 
 	private void retrieveCollectionFields(Session session, ClassDescriptor classDescriptor, Node parentNode, Object object,
diff --git a/src/main/java/org/apache/jackrabbit/ocm/manager/cache/impl/RequestObjectCacheImpl.java b/src/main/java/org/apache/jackrabbit/ocm/manager/cache/impl/RequestObjectCacheImpl.java
index ece2b77..95c3cab 100644
--- a/src/main/java/org/apache/jackrabbit/ocm/manager/cache/impl/RequestObjectCacheImpl.java
+++ b/src/main/java/org/apache/jackrabbit/ocm/manager/cache/impl/RequestObjectCacheImpl.java
@@ -23,10 +23,10 @@
 
 /**
  *
- * This is a simple cache implementation that can be used per retrieve requests. This avoids to load duplicated object
- * instance.
+ * This is a simple cache implementation that can be used per retrieve requests.
+ * This avoids to load duplicated object instance.
  * 
-* @author <a href="mailto:christophe.lombart@gmail.com">Lombart Christophe </a>
+ * @author <a href="mailto:christophe.lombart@gmail.com">Lombart Christophe </a>
  * 
 */
 public class RequestObjectCacheImpl implements ObjectCache {
diff --git a/src/main/java/org/apache/jackrabbit/ocm/manager/impl/ObjectContentManagerImpl.java b/src/main/java/org/apache/jackrabbit/ocm/manager/impl/ObjectContentManagerImpl.java
index 43fb42d..c5b4bb3 100644
--- a/src/main/java/org/apache/jackrabbit/ocm/manager/impl/ObjectContentManagerImpl.java
+++ b/src/main/java/org/apache/jackrabbit/ocm/manager/impl/ObjectContentManagerImpl.java
@@ -409,7 +409,9 @@ public void update(Object object) {
         }
 
         objectConverter.update(session, object);
-        requestObjectCache.ready(path, object);
+        // We do not use requestObjectCache.ready() here,
+        // because our changes might be rolled back later.
+        requestObjectCache.evict(path);
     }
 
     public void remove(String path) {
@@ -1126,9 +1128,7 @@ private void copy(Node srcNode, Node destNode) throws RepositoryException {
             Node node = iter.nextNode();
             Node child;
             // check if the subnode is autocreated
-            if (!node.getDefinition().isAutoCreated() 
-                    && node.getIndex()==1
-                    && destNode.hasNode(node.getName())) {
+            if (!node.getDefinition().isAutoCreated() && destNode.hasNode(node.getName())) {
                 child = destNode.getNode(node.getName());
             } else {
                 child = destNode.addNode(node.getName(), node.getPrimaryNodeType().getName());
