[ 
https://issues.apache.org/jira/browse/JCR-1448?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Christophe Lombart resolved JCR-1448.
-------------------------------------

    Resolution: Fixed

Fix applied. Thanks 

I also add a new unit test based on your example. 
Let me know if something is wrong. 



> nt:versionedChild problem
> -------------------------
>
>                 Key: JCR-1448
>                 URL: https://issues.apache.org/jira/browse/JCR-1448
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: jackrabbit-ocm
>    Affects Versions: 1.4
>            Reporter: Wes Smoak
>            Assignee: Christophe Lombart
>   Original Estimate: 0.5h
>  Remaining Estimate: 0.5h
>
> Problem occurs when both parent and child beans are versionable.  Jackrabbit 
> creates an nt:versionedChild node that is referenced by the parent node, 
> referencing the childs versionedHistory node of the child.  The current OCM 
> code does not handle this correctly and produces an error:  "Node type  
> 'nt:versionedChild' does not match descriptor node type 'nt:unstructured'"
> Below is a example code of the problem and a patch that appears to correctly 
> resolve the problem.
>  Within ObjectConverterImpl created the below method.
>         public Node getActualNode(Session session,Node node) throws
>  RepositoryException
>         {
>                 NodeType type = node.getPrimaryNodeType();
>                 if (type.getName().equals("nt:versionedChild"))
>                 {
>                         String uuid =
>  node.getProperty("jcr:childVersionHistory").getValue().getString();
>                         Node actualNode = session.getNodeByUUID(uuid);
>                         String name = actualNode.getName();
>                         actualNode = session.getNodeByUUID(name);
>                         return actualNode;
>                 }
>                 return node;
>         }
>  AND modified the following to call the above method
>         public Object getObject(Session session, Class clazz, String path)
>         {
>                 try {
>                         if (!session.itemExists(path)) {
>                                 return null;
>                         }
>                         if (requestObjectCache.isCached(path))
>                     {
>                         return requestObjectCache.getObject(path);
>                     }
>                         ClassDescriptor classDescriptor =
>  getClassDescriptor(clazz);
>                         checkNodeType(session, classDescriptor);
>                         Node node = (Node) session.getItem(path);
>                         if (!classDescriptor.isInterface()) {
>                                 {
>                                 node = getActualNode(session,node);
>                                 checkCompatiblePrimaryNodeTypes(session,
>  node, classDescriptor, true);
>                                 }
>                         }
>                         ClassDescriptor alternativeDescriptor = null;
>                         if
>  (classDescriptor.usesNodeTypePerHierarchyStrategy())
>  {
>                                 if
>  (node.hasProperty(ManagerConstant.DISCRIMINATOR_PROPERTY_NAME))
>  {
>                         String className =
>  node.getProperty(ManagerConstant.DISCRIMINATOR_PROPERTY_NAME
>  ).getValue().getString();
>                         alternativeDescriptor =
>  getClassDescriptor(ReflectionUtils.forName(className));
>                                 }
>                         } else {
>                                 if
>  (classDescriptor.usesNodeTypePerConcreteClassStrategy())
>  {
>                                         String nodeType =
>  node.getPrimaryNodeType().getName();
>                                         if
>  (!nodeType.equals(classDescriptor.getJcrType()))
>  {
>                                             alternativeDescriptor =
>  classDescriptor.getDescendantClassDescriptor(nodeType);
>                                             // in case we an alternative
>  could not be found by walking
>                                             // the class descriptor
>  hierarchy, check whether we
>  would
>                                             // have a descriptor for the
>  node type directly (which
>                                             // may the case if the class
>  descriptor hierarchy is
>                                             // incomplete due to missing
>  configuration. See JCR-1145
>                                             // for details.
>                                             if (alternativeDescriptor ==
>  null) {
>                                                 alternativeDescriptor =
>  mapper.getClassDescriptorByNodeType(nodeType);
>                                             }
>                                         }
>                                 }
>                         }
>                         // if we have an alternative class descriptor,
>  check whether its
>                         // extends (or is the same) as the requested class.
>                         if (alternativeDescriptor != null) {
>                             Class alternativeClazz =
>  ReflectionUtils.forName(alternativeDescriptor.getClassName());
>                             if (clazz.isAssignableFrom(alternativeClazz)) {
>                                 clazz = alternativeClazz;
>                                 classDescriptor = alternativeDescriptor;
>                             }
>                         }
>                         // ensure class is concrete (neither interface nor
>  abstract)
>                         if (clazz.isInterface() ||
>  Modifier.isAbstract(clazz.getModifiers())) {
>                             throw new JcrMappingException( "Cannot
>  instantiate non-concrete
>  class " + clazz.getName()
>                         + " for node " + path + " of type " +
>  node.getPrimaryNodeType().getName());
>                         }
>             Object object =
>  ReflectionUtils.newInstance(classDescriptor.getClassName());
>             if (! requestObjectCache.isCached(path))
>             {
>                           requestObjectCache.cache(path, object);
>             }
>             simpleFieldsHelp.retrieveSimpleFields(session,
>  classDescriptor, node, object);
>                         retrieveBeanFields(session, classDescriptor, node,
>  path, object, false);
>                         retrieveCollectionFields(session, classDescriptor,
>  node, object, false);
>                         return object;
>                 } catch (PathNotFoundException pnfe) {
>                         // HINT should never get here
>                         throw new
>  ObjectContentManagerException("Impossible to get
>  the object
>  at " + path, pnfe);
>                 } catch (RepositoryException re) {
>                         throw new
>  org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to
>  get the object at " + path, re);
>                 }
>         }
> >
> >
> >
> > > I am building a test application against OCM.  I have the following
> > > classes that are annotated for OCM.  The problem is that when I update
> > and
> > > version the root object PressRelease the Bean Author is versioned to
> > > nt:versionedChild.  While the OCM is checking for node type
> > compatibility
> > > it is throwing the following exception.  It looks like the
> > versionedChild
> > > is not handled correctly.  Any suggestions?
> > >
> > > I also attempted to retrieve the version based on the version name for
> > the
> > > rootVersion but also trapped. From a Version object how should I access
> > > each of the versioned entries?
> > >
> > > Thanks
> > > Wes
> > >
> > > @Node (jcrMixinTypes="mix:versionable")
> > > public class PressRelease
> > > {
> > >       @Field(path=true) String path;
> > >       @Field String title;
> > >       @Field Date pubDate;
> > >       @Field String content;
> > >       @Bean Author author;
> > >       @Collection (elementClassName=Comment.class) List<Comment>
> > comments = new
> > > ArrayList<Comment>();
> > >
> > >       public String getPath() {
> > >               return path;
> > >       }
> > >       public void setPath(String path) {
> > >               this.path = path;
> > >       }
> > >       public String getContent() {
> > >               return content;
> > >       }
> > >       public void setContent(String content) {
> > >               this.content = content;
> > >       }
> > >       public Date getPubDate() {
> > >               return pubDate;
> > >       }
> > >       public void setPubDate(Date pubDate) {
> > >               this.pubDate = pubDate;
> > >       }
> > >       public String getTitle() {
> > >               return title;
> > >       }
> > >       public void setTitle(String title) {
> > >               this.title = title;
> > >       }
> > >       public Author getAuthor() {
> > >               return author;
> > >       }
> > >       public void setAuthor(Author author) {
> > >               this.author = author;
> > >       }
> > >       public List<Comment> getComments() {
> > >               return comments;
> > >       }
> > >       public void setComments(List<Comment> comments) {
> > >               this.comments = comments;
> > >       }
> > >
> > >
> > > }
> > >
> > > @Node (jcrMixinTypes="mix:versionable")
> > > public class Author {
> > >
> > >       @Field(path=true) String path;
> > >       @Field String name;
> > >
> > >
> > >       public String getName() {
> > >               return name;
> > >       }
> > >       public void setName(String name) {
> > >               this.name = name;
> > >       }
> > >       public String getPath() {
> > >               return path;
> > >       }
> > >       public void setPath(String path) {
> > >               this.path = path;
> > >       }
> > >
> > > }
> > >
> > > MAIN
> > >
> > >       while (versionIterator.hasNext())
> > >       {
> > >           Version version = (Version) versionIterator.next();
> > >           System.out.println("version found : "+ version.getName() + " -
> > " +
> > >                                 version.getPath() + " - " +
> > > version.getCreated().getTime());
> > >
> > >
> > >           if (!version.getName().equals("jcr:rootVersion"))
> > >           {
> > >
> > > //      Get the object matching to the first version
> > >           pressRelease = (PressRelease)
> > > ocm.getObject("/newtutorial",version.getName());
> > >
> > >
> > >               System.out.println("PressRelease title : " +
> > pressRelease.getTitle());
> > >               System.out.println("             author: " +
> > > pressRelease.getAuthor().getName());
> > >               System.out.println("            content: " +
> > pressRelease.getContent());
> > >               List comments = pressRelease.getComments();
> > >               Iterator iterator = comments.iterator();
> > >               while (iterator.hasNext())
> > >               {
> > >                       comment = (Comment) iterator.next();
> > >                       System.out.println("Comment : <" + comment.getData()
> > + ">" +
> > > comment.getText());
> > >               }
> > >           }
> > >       }
> > >
> > >
> > > CONSOLE
> > > version found : jcr:rootVersion -
> > >
> > /jcr:system/jcr:versionStorage/fc/0b/fd/fc0bfd89-c487-4fbe-930f-d837e5dfed79/jcr:rootVersion
> > > - Thu Feb 28 15:54:42 EST 2008
> > > version found : 1.0 -
> > >
> > /jcr:system/jcr:versionStorage/fc/0b/fd/fc0bfd89-c487-4fbe-930f-d837e5dfed79/1.0
> > > - Thu Feb 28 15:54:59 EST 2008
> > > Exception in thread "main"
> > > org.apache.jackrabbit.ocm.exception.ObjectContentManagerException:
> > Cannot
> > > map object of type 'com..pc.repository.Author'. Node type
> > > 'nt:versionedChild' does not match descriptor node type
> > 'nt:unstructured'
> > >       at
> > >
> > org.apache.jackrabbit.ocm.manager.objectconverter.impl.ObjectConverterImpl.checkCompatiblePrimaryNodeTypes
> > (ObjectConverterImpl.java:552)
> > >       at
> > >
> > org.apache.jackrabbit.ocm.manager.objectconverter.impl.ObjectConverterImpl.getObject
> > (ObjectConverterImpl.java:361)
> > >       at
> > >
> > org.apache.jackrabbit.ocm.manager.beanconverter.impl.DefaultBeanConverterImpl.getObject
> > (DefaultBeanConverterImpl.java:80)
> > >       at
> > >
> > org.apache.jackrabbit.ocm.manager.objectconverter.impl.ObjectConverterImpl.retrieveBeanField
> > (ObjectConverterImpl.java:666)
> > >       at
> > >
> > org.apache.jackrabbit.ocm.manager.objectconverter.impl.ObjectConverterImpl.retrieveBeanFields
> > (ObjectConverterImpl.java:621)
> > >       at
> > >
> > org.apache.jackrabbit.ocm.manager.objectconverter.impl.ObjectConverterImpl.getObject
> > (ObjectConverterImpl.java:309)
> > >       at
> > >
> > org.apache.jackrabbit.ocm.manager.impl.ObjectContentManagerImpl.getObject(
> > ObjectContentManagerImpl.java:313)
> > >       at com.pc.repository.Main.main(Main.java:345)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to