[
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.