[
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.