[ https://issues.apache.org/jira/browse/JCR-1448?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Christophe Lombart reassigned JCR-1448: --------------------------------------- Assignee: Christophe Lombart > 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.