cancel
Showing results for 
Search instead for 
Did you mean: 

Create new version with Behaviours/Policies

zhihailiu
Champ on-the-rise
Champ on-the-rise

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 (statusSmiley Frustratedtatus[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.

5 REPLIES 5

zhihailiu
Champ on-the-rise
Champ on-the-rise

Forget to specify that it is tested on Alfresco 5.0

afaust
Legendary Innovator
Legendary Innovator

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.

zhihailiu
Champ on-the-rise
Champ on-the-rise

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.

afaust
Legendary Innovator
Legendary Innovator

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.

zhihailiu
Champ on-the-rise
Champ on-the-rise

Thank you!