cancel
Showing results for 
Search instead for 
Did you mean: 

OnDeleteChildAssociationPolicy problem

nowhere
Champ in-the-making
Champ in-the-making
Hi all,
I have created my class as follow:

public class MyClass
   implements NodeServicePolicies.OnCreateChildAssociationPolicy,
            NodeServicePolicies.OnDeleteChildAssociationPolicy {

   // Dependencies
    private NodeService nodeService;
    private PolicyComponent policyComponent;
    private ServiceRegistry serviceRegistry;
    // Behaviours
    private Behaviour onCreateNode;
    private Behaviour onDeleteNode;
   
    private Logger logger = Logger.getLogger(MyClass.class);
   
    public void init() {
       if (logger.isDebugEnabled()) logger.debug("Initializing behaviors");
       
        // Create behaviours
        this.onCreateNode = new JavaBehaviour(this, "onCreateChildAssociation", NotificationFrequency.TRANSACTION_COMMIT);
        this.onDeleteNode = new JavaBehaviour(this, "onDeleteChildAssociation", NotificationFrequency.TRANSACTION_COMMIT);

        // Bind behaviours to node policies
        this.policyComponent.bindAssociationBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateChildAssociation"), QName.createQName(myModel.NAMESPACE_MY_CONTENT_MODEL, myModel.ASPECT_MY_COMPONIBILE), QName.createQName(myModel.NAMESPACE_MT_CONTENT_MODEL, myModel.ASSN_TIPO1), this.onCreateNode);
        this.policyComponent.bindAssociationBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteChildAssociation"), QName.createQName(visiteIspettiveModel.NAMESPACE_VISIT_CONTENT_MODEL, myModel.ASPECT_MY_COMPONIBILE), QName.createQName(myModel.NAMESPACE_MY_CONTENT_MODEL, myModel.ASSN_TIPO1), this.onDeleteNode);
     }

that overrides following methods:

   
public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean arg1) {
      if (logger.isDebugEnabled()) logger.debug("Inside onCreateNode");      
      method(childAssocRef);
      
   }

public void onDeleteChildAssociation(ChildAssociationRef childAssocRef) {
      if (logger.isDebugEnabled()) logger.debug("Inside onDeleteNode");
      method(childAssocRef);
      
   }

Now, my problem is that if I create a node with following code :

NodeRef mynode = nodeService.createNode(nodoContenitore, QName.createQName(myModel.NAMESPACE_MY_CONTENT_MODEL , myModel.ASSN_TIPO1) ,ContentModel.TYPE_CONTENT, QName.createQName(myModel.NAMESPACE_MY_CONTENT_MODEL , myModel.TYPE_MY_TYPE)).getChildRef();

It executes the behaviour and the onCreateChildAssociation method, so it works.

But the behaviour doesn't start if I delete an association with the following code

nodeService.removeChildAssociation(assRef);

where getTypeQName(assRef) is  {http://www.mymodel.com/model/content/1.0}ass1

It's to say that are valid the following:
public static final String NAMESPACE_MY_CONTENT_MODEL  = "http://www.mymodel.com/model/content/1.0";
public static final String ASSN_TIPO1 = "ass1";

and association "ass1" is defined in a custom model of mine:


<aspect name="my:aspectDefined">
      <title>Title here</title>
      <properties>
   
      </properties>
      <associations>
         <child-association name="my:ass1">
            <title></title>
            <source>
               <mandatory>false</mandatory>
               <many>true</many>
            </source>
            <target>
               <class>my:mydocument</class>
               <mandatory>false</mandatory>
               <many>true</many>
            </target>
         </child-association>
         
      </associations>
   </aspect>

Where am I in wrong in defining the onDeleteChildAssociation behaviour? Can you help me? I didn't find much documentation around.
Thanks!  Smiley Happy
2 REPLIES 2

hpalma
Champ in-the-making
Champ in-the-making
I'm also getting this problem. The OnDeleteChildAssociation event is never called.
Did you find a solution for this ?

nowhere
Champ in-the-making
Champ in-the-making
Hi hpalma,
I found an alternative way for the problem in the post…
But, after your post, I had a look at alfresco code and I found a possible cause.

In DbNodeServiceImpl the method "removeChildAssociation" has the following code (a piece):

if (assocRef.isPrimary())
        {    NodeRef childNodeRef = assocRef.getChildRef();
            // Delete the child node
            this.deleteNode(childNodeRef);
            // Done
            return true;
        }else
        {
            // Delete the association
            invokeBeforeDeleteChildAssociation(childAssocRef);
            nodeDaoService.deleteChildAssoc(assocId);
            invokeOnDeleteChildAssociation(childAssocRef);
            // Index
            nodeIndexer.indexDeleteChildAssociation(childAssocRef);
            // Done
            return true;
        }

So, probably, your as mine is a primary association and "invokeOnDeleteChildAssociation(childAssocRef)" is never called.
As test I rebuild alfresco with bold lines addes as follows:

if (assocRef.isPrimary())
        {  

            NodeRef childNodeRef = assocRef.getChildRef();
           
            [b]invokeBeforeDeleteChildAssociation(childAssocRef);[/b]
            // Delete the child node
            this.deleteNode(childNodeRef);
           
            [b]invokeOnDeleteChildAssociation(childAssocRef);[/b]
            // Done
            return true;
        }
        else
        {
            // Delete the association
            invokeBeforeDeleteChildAssociation(childAssocRef);
            nodeDaoService.deleteChildAssoc(assocId);
            invokeOnDeleteChildAssociation(childAssocRef);
            // Index
            nodeIndexer.indexDeleteChildAssociation(childAssocRef);
            // Done
            return true;
        }

and the OnDeleteChildAssociation event is triggered. But I don't know much about primary association so I can't figure out why alfresco code is in that way.  Smiley Surprisedops: 
We could ask more expert forum members to explain us this.  :roll:

Also, since "deleteNode" is called in case of primary association (and "deleteNode" calls "invokeOnDeleteNode" and "invokeBeforeDeleteNode") you could take a chance and substitute your "onDeleteChildAssociation" policy with onDeleteNode or beforeDeleteNode policy on your child node type.

That's all…hoping it could be at least a good start point…let me know!

*Edit: bold is not visible in code tag, I left the b tag to make visible the changes.