[ https://issues.apache.org/jira/browse/OCM-34?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Craig Schaefer updated OCM-34: ------------------------------ Attachment: OCM-34.patch Fix as described in original posting of this bug. > referential integrity problem due to ObjectContentManagerImpl usage of > ObjectCache > ---------------------------------------------------------------------------------- > > Key: OCM-34 > URL: https://issues.apache.org/jira/browse/OCM-34 > Project: Jackrabbit OCM > Issue Type: Bug > Reporter: Craig Schaefer > Attachments: OCM-34.patch > > > It appears that there is an ObjectCache which lives for the lifetime of an > ObjectContentManagerImpl instance. In most cases the reference to the > ObjectCache is shared with the ObjectConverterImpl (which is also contained > by ObjectContentManagerImpl). > Normally any of the ObjectContentManagerImpl #getObject(String path), > #getObjectByUuid(String uuid), #getObject(String path, String versionName) > #getObject(Class objectClass, String path, String versionName) behaviours > cause the ObjectCache to be populated by as the ObjectConverterImpl is used. > At the end of ObjectConverterImpl usage the ObjectCache is always cleared. > However if I use ObjectContentManagerImpl#retrieveAllMappedAttributes(Object > object) or retrieveMappedAttribute(Object object, String attributeName) then > the ObjectConverterImpl is also used and as a side effect the ObjectCache is > updated but never cleared. > Therefore, if I now start deleting objects and then re-adding them at the > same path the objectCache is used during the insert process and it refers to > old objects which were deleted. > e.g. > myObject = ocm#getObject(/path/to/object) > ## at this point ObjectCache is empty again > ocm#retrieveMappedAttribute(myObject, "attributeName") - where attribute > is a reference to another object > ## at this point ObjectCache is still populated with referencedObject > ocm#delete(myObject) > ocm#delete(referencedObject) > ocm#save() > ## at this point ObjectCache is still populated with referencedObject > ocm#insert(newMyObject) - where newMyObject has same path as myObject > ## at this point the ObjectConverterImpl has refered to the ObjectCache and > mapped the reference attribute to the old referencedObject in ObjectCache. > ocm#save() > ## at this point the save fails due to referential integrity > The fix was to extend ObjectContentManagerImpl to fix > #retrieveAllMappedAttributes(Object object) or retrieveMappedAttribute(Object > object, String attributeName) as well as #save() to provide coverage for any > loose cases. If jackrabbit-ocm were to be updated instead the deltas to > ObjectContentManagerImpl would be: > public void retrieveMappedAttribute(Object object, String attributeName) { > objectConverter.retrieveMappedAttribute(session, object, > attributeName); > + requestObjectCache.clear() > } > public void retrieveAllMappedAttributes(Object object) { > objectConverter.retrieveAllMappedAttributes(session, object); > + requestObjectCache.clear() > } > public void save() { > try { > this.session.save(); > } catch (NoSuchNodeTypeException nsnte) { > throw new JcrMappingException("Cannot persist current session > changes. An unknown node type was used.", nsnte); > } catch (javax.jcr.version.VersionException ve) { > throw new VersionException("Cannot persist current session > changes. Attempt to overwrite checked-in node", ve); > } catch (LockException le) { > throw new ObjectContentManagerException("Cannot persist current > session changes. Violation of a lock detected", le); > } catch (RepositoryException e) { > throw new ObjectContentManagerException("Cannot persist current > session changes.", e); > + } finally { > + requestObjectCache.clear() > + } > } > This fix works fine in our coverage suite. -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.