12-16-2016 02:50 PM
I have a rather simple behaviour/policy implementation. When an aspect "signedDateAspect" is added to a document, check and set the value for the property "signedDate". The code (relevant part) is below.
public class SignedDateAspectPolicy implements NodeServicePolicies.OnAddAspectPolicy {
public void init() {
this.onAddAspectBehavior = new JavaBehaviour(this, "onAddAspect", NotificationFrequency.TRANSACTION_COMMIT);
this.policyComponent.bindClassBehaviour(NodeServicePolicies.OnAddAspectPolicy.QNAME,
MycContentModel.ASPECT_SIGNED_DATE, this.onAddAspectBehavior);
}
@Override
public void onAddAspect(NodeRef nodeRef, QName aspectTypeQName) {
Serializable propSignedDate = this.nodeService.getProperty(nodeRef, MycContentModel.PROP_SIGNED_DATE);
if (propSignedDate == null) {
Date propModified = (Date) this.nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED);
this.nodeService.setProperty(nodeRef, MycContentModel.PROP_SIGNED_DATE, propModified);
}
}
}
It works fine until a new version of the document is uploaded. Steps to replicate:
1. Upload a document - pass
2. Add the aspect - pass
3. Upload a new version - fail
The error in log is
Caused by: org.alfresco.service.cmr.repository.InvalidNodeRefException: Node does not exist: workspace://SpacesStore/e3a32cce-de90-4957-b026-7ef683e8a713 (statustatus[id=12279changeTxnId=3cc18e2f-c628-40cd-9f71-640a86de9d39, dbTxnId=4550, deleted=true])
I had to add a check at the beginning of onAddAspect method.
if (!this.nodeService.exists(nodeRef)) {
return;
}
What is the node "workspace://SpacesStore/e3a32cce-de90-4957-b026-7ef683e8a713" that is created in this process? Why doesn't it exist (did it get deleted)? Could someone explain the inner working of how a new version is created in Alfresco? Thanks.
12-16-2016 02:57 PM
Forget to specify that it is tested on Alfresco 5.0
12-18-2016 10:03 AM
Your issue likely is related to the fact that you are using TRANSACTION_COMMIT for binding the policy. Unfortunately I see that quite a lot in blog posts or other community examples without people understanding implications / side effects of it. During "Upload New Version" a temporary node will be created (a working copy since "Upload New Version" consists of a check-out/check-in cycle) which will get deleted before the operation is complete. This node will cause the behaviour to be triggered, but since you specified TRANSACTION_COMMIT it will only be called at the end of the transaction after the temporary node has already been deleted again.
This is not related to how versions are created in general - it is just a specific of the "Upload New Version" UI action, which actually simulates three user actions (check-out, edit the working copy, check-in) to ensure some behavioural consistency to different ways a user could interact with the system and trigger these actions invidiually.
12-18-2016 11:47 AM
Axel,
Thank you for your response. That clearly explained check in/out in "Upload New Version" and resulted "node not found". Extremely helpful.
As for the fix, do you think the "return if not exists" approach is acceptable? Or it should switch to other binding such as EVERY_EVENT?
Thanks again.
12-18-2016 03:18 PM
I prefer to use the EVERY_EVENT notification frequency in almost all instances. But that does not absolve the programmer from doing the necessary pre-condition checks, and "return if not exists" is one of the proper checks to perform for TRANSACTION_COMMIT. Another would be "is the node part of workspace://SpacesStore" by comparing the StoreRef of the NodeRef against the constant in StoreRef-class.
12-19-2016 08:58 AM
Thank you!
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.