cancel
Showing results for 
Search instead for 
Did you mean: 

Content Model Change?

dannyl999
Champ in-the-making
Champ in-the-making
Hi,

I was upgrading our Alfresco 3.2r system to 4.0.2, and we successfully upgraded it to 3.4.10.  We started to upgrade to 4.0.2 and got to the point where it started up succesfully.  But then, we came across this error in one of our custom Java-backed webscripts:
java.lang.IllegalArgumentException: NodeRef may not be null for calls to NodeService.  Check client code.
   at org.alfresco.repo.node.MLPropertyInterceptor.getPivotNodeRef(MLPropertyInterceptor.java:321)
   at org.alfresco.repo.node.MLPropertyInterceptor.invoke(MLPropertyInterceptor.java:162)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.node.NodeRefPropertyMethodInterceptor.invoke(NodeRefPropertyMethodInterceptor.java:198)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.node.NodeRefPropertyMethodInterceptor.invoke(NodeRefPropertyMethodInterceptor.java:198)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy8.getProperty(Unknown Source)
   at sun.reflect.GeneratedMethodAccessor248.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.alfresco.repo.audit.DisableAuditableBehaviourInterceptor.invoke(DisableAuditableBehaviourInterceptor.java:113)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:80)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:46)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:153)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.transaction.RetryingTransactionInterceptor$1.execute(RetryingTransactionInterceptor.java:69)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:388)
   at org.alfresco.repo.transaction.RetryingTransactionInterceptor.invoke(RetryingTransactionInterceptor.java:59)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy8.getProperty(Unknown Source)
   at gov.ic.dodiis.habeas.webscripts.record.BaseGetRecord.buildJSONPropObject(BaseGetRecord.java:218)
   at gov.ic.dodiis.habeas.webscripts.record.SearchRecord.buildJSONArray(SearchRecord.java:697)
   at gov.ic.dodiis.habeas.webscripts.record.SearchRecord.buildJSON(SearchRecord.java:685)
   at gov.ic.dodiis.habeas.webscripts.record.SearchRecord.runScript(SearchRecord.java:97)
   at gov.ic.dodiis.habeas.webscripts.HabeasWebscript.execute(HabeasWebscript.java:50)
   at org.alfresco.repo.web.scripts.RepositoryContainer$2.execute(RepositoryContainer.java:414)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:388)
   at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecute(RepositoryContainer.java:476)
   at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecuteAs(RepositoryContainer.java:514)
   at org.alfresco.repo.web.scripts.RepositoryContainer.executeScript(RepositoryContainer.java:330)
   at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:377)
   at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:209)
   at org.springframework.extensions.webscripts.servlet.WebScriptServlet.service(WebScriptServlet.java:118)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.repo.web.filter.beans.NullFilter.doFilter(NullFilter.java:68)
   at sun.reflect.GeneratedMethodAccessor444.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:116)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy250.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:82)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.repo.web.filter.beans.NullFilter.doFilter(NullFilter.java:68)
   at sun.reflect.GeneratedMethodAccessor444.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:116)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy250.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:82)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.web.app.servlet.GlobalLocalizationFilter.doFilter(GlobalLocalizationFilter.java:58)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:470)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
   at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:448)
   at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:399)
   at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1675)
   at java.lang.Thread.run(Thread.java:662)
java.lang.IllegalArgumentException: NodeRef may not be null for calls to NodeService.  Check client code.
   at org.alfresco.repo.node.MLPropertyInterceptor.getPivotNodeRef(MLPropertyInterceptor.java:321)
   at org.alfresco.repo.node.MLPropertyInterceptor.invoke(MLPropertyInterceptor.java:162)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.node.NodeRefPropertyMethodInterceptor.invoke(NodeRefPropertyMethodInterceptor.java:198)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.node.NodeRefPropertyMethodInterceptor.invoke(NodeRefPropertyMethodInterceptor.java:198)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy8.getProperty(Unknown Source)
   at sun.reflect.GeneratedMethodAccessor248.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.alfresco.repo.audit.DisableAuditableBehaviourInterceptor.invoke(DisableAuditableBehaviourInterceptor.java:113)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:80)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:46)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:153)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.transaction.RetryingTransactionInterceptor$1.execute(RetryingTransactionInterceptor.java:69)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:388)
   at org.alfresco.repo.transaction.RetryingTransactionInterceptor.invoke(RetryingTransactionInterceptor.java:59)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy8.getProperty(Unknown Source)
   at gov.ic.dodiis.habeas.webscripts.record.BaseGetRecord.buildJSONPropObject(BaseGetRecord.java:218)
   at gov.ic.dodiis.habeas.webscripts.record.SearchRecord.buildJSONArray(SearchRecord.java:697)
   at gov.ic.dodiis.habeas.webscripts.record.SearchRecord.buildJSON(SearchRecord.java:685)
   at gov.ic.dodiis.habeas.webscripts.record.SearchRecord.runScript(SearchRecord.java:97)
   at gov.ic.dodiis.habeas.webscripts.HabeasWebscript.execute(HabeasWebscript.java:50)
   at org.alfresco.repo.web.scripts.RepositoryContainer$2.execute(RepositoryContainer.java:414)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:388)
   at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecute(RepositoryContainer.java:476)
   at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecuteAs(RepositoryContainer.java:514)
   at org.alfresco.repo.web.scripts.RepositoryContainer.executeScript(RepositoryContainer.java:330)
   at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:377)
   at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:209)
   at org.springframework.extensions.webscripts.servlet.WebScriptServlet.service(WebScriptServlet.java:118)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.repo.web.filter.beans.NullFilter.doFilter(NullFilter.java:68)
   at sun.reflect.GeneratedMethodAccessor444.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:116)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy250.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:82)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.repo.web.filter.beans.NullFilter.doFilter(NullFilter.java:68)
   at sun.reflect.GeneratedMethodAccessor444.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:116)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy250.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:82)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.web.app.servlet.GlobalLocalizationFilter.doFilter(GlobalLocalizationFilter.java:58)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:470)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
   at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:448)
   at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:399)
   at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1675)
   at java.lang.Thread.run(Thread.java:662)

This error was caused by getting a null from calling nodeService.getWorkingCopy().  I checked out if the nodeRef had a working copy through the Alfresco Node Browser, and I found it.  So I digged deeper and I found out that the cm content model had changed.  An aspect called cm:checkedOut was added.

      <aspect name="cm:checkedOut">
         <title>Checked Out</title>
         <associations>
            <association name="cm:workingcopylink">
               <source>
                  <mandatory>true</mandatory>
                  <many>false</many>
               </source>
               <target>
                  <class>cm:workingcopy</class>
                  <mandatory>true</mandatory>
                  <many>false</many>
               </target>
            </association>
         </associations>
         <mandatory-aspects>
            <aspect>cm:lockable</aspect>
         </mandatory-aspects>
      </aspect>

So basically, any files that are checked out in 4.0.2 should now have the cm:checkedOut aspect.  It makes sense why they did it: to make it easier to get the workingcopy since it now has a direct association link.  But all of the files that was still checked out before Alfresco 4.0 did not contain this aspect.  So I'm guessing the nodeService.getWorkingCopy() got modified to use the new association, and since the old checked out files didn't have the aspect, it returned a null.

I would like to avoid creating a migration script to undo check out all the files before upgrading to 4.0.2 since that would probably make our customer angry.  It might be possible to somehow add the aspect to all of the checked out files and wire them all up somehow, if I can figure out a way to find the working copy of all the checked out files.  I would like to avoid that, too, if at all possible.

I'm just wondering if I missed a step somewhere during the upgrade process.
5 REPLIES 5

mitpatoliya
Star Collaborator
Star Collaborator
Hi danny,
Try this
         NodeRef workingCopyRef = this.getCheckOutCheckInService().getWorkingCopy(getDocument().getNodeRef());

This is supported in Alfresco4.0.

dannyl999
Champ in-the-making
Champ in-the-making
Sorry about that.  I didn't mean nodeService.getWorkingCopy().  I meant checkInCheckOutService.getWorkingCopy() is returning NULL.  Again, this is only for the files that were checked out in an older version of Alfresco.  I am able to get the working copy for files that were checked out in Alfresco 4.

So the used case would be:
1.  Start off with Alfresco 3.4.10
2.  Check out a file
3.  Upgrade to 4.0.2
4.  Call CheckOutCheckInService.getWorkingCopy on the file that was checked out.

Result:  NULL

I hope that makes more sense.

mitpatoliya
Star Collaborator
Star Collaborator
Ohh okey use case clear.
So, what you need to do in this case is as follow.
Check which aspect is applied to the working copies of all document.
I guess in 3.4 it was "cm:workingcopy" aspect by looking at the content model of 3.4

So you can grab all such documents in and add the new checkedOut aspect to it.

Also there is one more aspect called "cm:copiedfrom" that i guess gives you the original document.

So, you populate the values of  "cm:workingcopy" aspect and apply that.

You can create alfresco javascript for that.

dannyl999
Champ in-the-making
Champ in-the-making
Gotcha.  I was hoping I didn't have to create this migration script, and that I missed a step somewhere during the upgrade installation.

So, the steps I am hoping to do:
1.  Find all nodes with the aspect cm:workingcopy
2.  For each node, do the following:
2a.  Get nodeId from the property cm:source (which I believe comes from the cm:copiedfrom)
2b.  Add the aspect cm:checkedOut
2c.  Add a cm:workingcopylink association between the current node and the node from step 2a
2d.  Remove the cm:workingcopy and the cm:copiedfrom aspect (Hoping this works, even though it doesn't exist in the content model)
3.  Test check in and undo check out.

I'll see what happens.  Thanks.

mitpatoliya
Star Collaborator
Star Collaborator
Yes, that's the way to go.
Best of luck  😎