You are viewing a plain text version of this content. The canonical link for it is here.
Posted to graffito-dev@incubator.apache.org by Dan Connelly <ds...@adelphia.net> on 2006/09/03 20:52:08 UTC

How can aggregation be mapped in OCM?

How do you express aggregated, not contained, bean references in the OCM?  

An aggregate bean ref would (presumably) get persisted as a uuid uri, 
not as a content sub-node.    (Path references might be okay instead of 
uuids.)

If I map naively with two classes that where each has the other as a 
bean element, then pm.insert(rootObj) will traverse this loop 
endlessly.   The rootObj class has proper containment of both these 
mutually referencing classes.

       -- Dan

Re: How can aggregation be mapped in OCM?

Posted by Dan Connelly <ds...@adelphia.net>.
Okay.   No rush here.

I am already moving ahead with the solution I proposed, but I am have 
run into an obstacle, as follows:

Just to update you:

I have a new class "ReferencingBeanConverterImpl" that extends 
AbstractBeanConverterImpl.

For my new class, the insert method has this *temporary* code:

        Reference ref = new Reference();
        try {
            ref.setUuid(parentNode.getUUID());
        } catch (UnsupportedRepositoryOperationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (javax.jcr.RepositoryException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        objectConverter.insert(session, parentNode, 
descriptor.getJcrName(), ref);
      

This replaces the bean by a Reference to the parent.    Next step is to 
have it to have Reference hold uuid of the object's node in the Repository.

So far so good, with one slight annoyance:   To make this work, I have 
described the Reference class in the mapping file.

Reference is an internal class that should be registered and handled 
automatically.  

Where is the hook that allows me to generate the descriptor for 
Reference class in the code.

       -- Dan



Christophe Lombart wrote:

> Sorry for the delay, I will come back on this mail tommorow. Some
> urgent stuffs to do.
>
>
> Thanks,
> Christophe
>
> On 9/5/06, Dan Connelly <ds...@adelphia.net> wrote:
>
>> Christophe
>>
>> I don't have any fully developed use cases yet, but, yes, there are some
>> pre-conditions that I do accept.
>>
>> In particular, I accept that every model object will have a jcrNodeType
>> that has mix:referenceable as a supertype.
>>
>> For instance:
>>
>>   <nodeType name="graffito:object" isMixin="false">
>>     <supertypes>
>>       <supertype>mix:referenceable</supertype>
>>       <supertype>nt:unstructured</supertype>
>>     </supertypes>
>>   </nodeType>
>>
>> This graffito:object type would be specified as the jcrNodeType of the
>> model classes in the ocm mapping.   In addition to that usage, I would
>> also have code for persisting references (pointers) using the same
>> jcrNodeType.   So, where the parent node is already know, the reference
>> node to a bean in that parent can be constructed as follows :
>>
>>      QueryResult qr = query.execute();   // query criteria based on
>> object identity, ie. id="true"
>>      NodeIterator matches = qr.getNodes();
>>      if ( matches.size() > 0 ) {
>>           Node theNode = matches.next();  // take the first one
>>           String uuid = theNode.getUUID();   // assume graffito:object
>> node type
>>           Node refNode = parent.addNode(fieldName,"graffito:object");
>>           refNode.setProperty(PersistenceConstant.MUST_DEREFERENCE,
>> uuid, PropertyType.REFERENCE);
>>      }
>>
>> An alternative to querying would be to could keep a HashMap associated
>> with the JCR Session.   In this HashMap (global for the session), the
>> object to persist is the key and its uuid string is the value.   If the
>> lookup on the object returns null, then the object has not been inserted
>> yet.  Insert it now and record its uuid in the hash map.
>>
>> Any node in the Repository having a *property* whose name is
>> PerstenceConstant.MUST_DEREFERENCE and whose value type is
>> PropteryType.REFERENCE should not be used directly.   It should be
>> de-referenced through the node with that uuid, regards of the path to
>> that node.    De-referencing is node is done as node =
>> session.getNodeByUUID(String uuid) and bean converter needs to handle
>> all the exceptions that could be thrown by that call.
>>
>> Pointer chains might exist for multi-step de-referencing.   Maintenance
>> of such pointer chains can be a tricky because there is no real
>> difference between pointers and data, which is the problem you find in
>> the C language.    However, I think that issue is only a small concern
>> for my use case(s) and I will defer it.
>>
>>        -- Dan
>>
>>
>>
>> Christophe Lombart wrote:
>>
>> > On 9/5/06, Dan Connelly <ds...@adelphia.net> wrote:
>> >
>> >> Christophe:
>> >>
>> >> Okay.   But it does get a little tricky, as follows:
>> >>
>> >> ReferencingBeanConverterImpl#insert operation:   This must actually
>> >> create a node for the bean if there is no node for its already.   
>> If the
>> >> bean has a node (elsewhere),  then a reference node is inserted
>> >>
>> >
>> > If I remember correctly, a referencable node matches to a JCR property
>> > in the target node.
>> > Why to create subnode ? Sorry if  I'm wrong because I have not all the
>> > details on the JCR spec. I have to review it.
>> >
>> >
>> >> ContainedBeanConverterImpl#insert operation.   This must move the 
>> node
>> >> if it already exists elsewhere, leaving a reference node in its
>> >> place.    Otherwise, it creates and inserts the node for the bean.
>> >>
>> > What do you mean by moving the node if it is already exist. How to
>> > check if it is the same node ? I don't understand all the details
>> > here. Can you give more information ?
>> >
>> >> Is this what you are suggesting?
>> >>
>> >>        -- Dan
>> >
>> >
>> > Without some use cases, it is difficult to gives exact information but
>> > here are some thoughts on JCR references. This is just to start some
>> > discussions because I don't know if we have to implement the same
>> > features.
>> >
>> > Precondition to map a jcr referenceable node to a bean
>> > 
>> -------------------------------------------------------------------------------- 
>>
>> >
>> > * The referenceable node already exists in the repo (of course based
>> > on mix:referencable).
>> > * If I remember correctly the JCR spec : the reference is stored in a
>> > property in the target node.
>> >
>> > Mapping file
>> > ------------------
>> > We have to check how to specifiy the references in the mapping file.
>> > We should support references from a bean descriptor but also from a
>> > collection descriptor. I mean it should be possible to create a
>> > collection containing some references to other nodes (objects).
>> >
>> > If we accept this situation, we have to find a way to
>> >
>> > 1/ [When retrieving the object containing the reference] : Map a JCR
>> > node property to a java bean and in the case of a collection of
>> > references, a series of JCR node properties into a Java collection (or
>> > map).
>> >
>> > 2/ [When updating, inserting the object containing the reference] :
>> > Map a bean attribute into a JCR property (UUID value) or a collection
>> > attribute into a serie of JCR properties.
>> >
>> > Let me know if I'm wrong because I don't remember all the details from
>> > JCR spec.
>> > We have also to check how to avoid some performance issues (is it
>> > possible to use the existing features like proxy, auto-retrieve,
>> > auto-update, ...).
>> >
>> > Ohoh It is more than I expected 2 days ago :-(
>> >
>> >
>> > Christophe
>> >
>>
>>
>
>


Nw pre-condition, new solution.

Posted by Dan Connelly <ds...@adelphia.net>.
Christophe:

Here is a new pre-condition on my use case.   Thinking of the problem 
this way, I have a new working solution.

New pre-condition:   Any object in my domain can give back  its (proper) 
containment hierarchy.    This maps fairly directly and generally to an 
absolute JCR path, provided that there is an id field in every class of 
this hierarchy.    I will assume, as a further pre-condition, that id 
fields have been fully mapped.   (But perhaps this works better if beans 
could also be marked as ids.)   

Function:   I am attempting to insert an object into jcr space under a 
given parent.  The parent already exists in jcr space due to the 
depth-first execution order.   Therefore, the inserting abs path is 
known.    The containment hierarchy fully exists in object space, but is 
incomplete and in the process of being built in jcr space.    Every 
object being inserted has two abs paths, its containment abs path (from 
the new precondition) and its insertion abs path, as given in the 
invocation.   These 2 paths may be identical.

Here is the new logic for my new solution.

If the two abs paths are the same (by value) and if the object already 
exists on that abs path in jcr space, then there is nothing to do.   
Done.   (Note:  The inserted object and found object do *not* need to be 
identical.)

If the two abs paths are the same (by value) but there is no object in 
jcr space for this abs path , merely insert normally on the (insertion) 
abs path.  The parent already exists on the insertion path due to the 
depth-first insertion ordering.     Done.

In the case where the two abs paths are different (by value), then look 
first for the node on the containment abs path in jcr space.   If 
anything exists there, then insert a Reference object to that node at 
the *invoked* insertion abs path.   Done.

If the is not node (yet) at the containment abs path in jcr space, I 
look for its containing parent node on the containment abs path in jcr 
space.    If that exists, insert the current object under the 
containment parent and *also* insert a Reference to the node just 
inserted on the invoked insertion abs path.   If the containment parent 
is not in jcr space, recurse up the containment path until  an ancestor 
(or root) is found in jcr space.   Then I unwind the recursion, 
inserting all the containment ancestors.   Finally,  insert the object 
itself under its containment parent and *also* insert a Reference to the 
node just inserted on the invoked insertion abs path.

I can build this solution with a MyBeanConverterImpl class which will 
compute the containment abs path internally using the standard 
BeanConverter interface.    

This was not my preferred solution.    I wanted to offer a completely 
general solution with classes ReferencingBeanConverterImpl and 
ContainedBeanConverterImpl, both implementing the BeanConverter 
interface.    Then the ocm mapping file would then provide the 
containment hierarchy (well enough).   This solution would have avoided 
the pre-condition I am using here that a unique containment hierarchy is 
encoded in the object model.     However, I do not want to take the time 
right now to find a query (in place of the containment path query) which 
would fit enough other use cases.    I may come back to that solution at 
another time and offer it back to the Graffito team. 

       -- Dan


Christophe Lombart wrote:

> Sorry for the delay, I will come back on this mail tommorow. Some
> urgent stuffs to do.
>
>
> Thanks,
> Christophe
>
> On 9/5/06, Dan Connelly <ds...@adelphia.net> wrote:
>
>> Christophe
>>
>> I don't have any fully developed use cases yet, but, yes, there are some
>> pre-conditions that I do accept.
>>
>> In particular, I accept that every model object will have a jcrNodeType
>> that has mix:referenceable as a supertype.
>>
>> For instance:
>>
>>   <nodeType name="graffito:object" isMixin="false">
>>     <supertypes>
>>       <supertype>mix:referenceable</supertype>
>>       <supertype>nt:unstructured</supertype>
>>     </supertypes>
>>   </nodeType>
>>
>> This graffito:object type would be specified as the jcrNodeType of the
>> model classes in the ocm mapping.   In addition to that usage, I would
>> also have code for persisting references (pointers) using the same
>> jcrNodeType.   So, where the parent node is already know, the reference
>> node to a bean in that parent can be constructed as follows :
>>
>>      QueryResult qr = query.execute();   // query criteria based on
>> object identity, ie. id="true"
>>      NodeIterator matches = qr.getNodes();
>>      if ( matches.size() > 0 ) {
>>           Node theNode = matches.next();  // take the first one
>>           String uuid = theNode.getUUID();   // assume graffito:object
>> node type
>>           Node refNode = parent.addNode(fieldName,"graffito:object");
>>           refNode.setProperty(PersistenceConstant.MUST_DEREFERENCE,
>> uuid, PropertyType.REFERENCE);
>>      }
>>
>> An alternative to querying would be to could keep a HashMap associated
>> with the JCR Session.   In this HashMap (global for the session), the
>> object to persist is the key and its uuid string is the value.   If the
>> lookup on the object returns null, then the object has not been inserted
>> yet.  Insert it now and record its uuid in the hash map.
>>
>> Any node in the Repository having a *property* whose name is
>> PerstenceConstant.MUST_DEREFERENCE and whose value type is
>> PropteryType.REFERENCE should not be used directly.   It should be
>> de-referenced through the node with that uuid, regards of the path to
>> that node.    De-referencing is node is done as node =
>> session.getNodeByUUID(String uuid) and bean converter needs to handle
>> all the exceptions that could be thrown by that call.
>>
>> Pointer chains might exist for multi-step de-referencing.   Maintenance
>> of such pointer chains can be a tricky because there is no real
>> difference between pointers and data, which is the problem you find in
>> the C language.    However, I think that issue is only a small concern
>> for my use case(s) and I will defer it.
>>
>>        -- Dan
>>
>>
>>
>> Christophe Lombart wrote:
>>
>> > On 9/5/06, Dan Connelly <ds...@adelphia.net> wrote:
>> >
>> >> Christophe:
>> >>
>> >> Okay.   But it does get a little tricky, as follows:
>> >>
>> >> ReferencingBeanConverterImpl#insert operation:   This must actually
>> >> create a node for the bean if there is no node for its already.   
>> If the
>> >> bean has a node (elsewhere),  then a reference node is inserted
>> >>
>> >
>> > If I remember correctly, a referencable node matches to a JCR property
>> > in the target node.
>> > Why to create subnode ? Sorry if  I'm wrong because I have not all the
>> > details on the JCR spec. I have to review it.
>> >
>> >
>> >> ContainedBeanConverterImpl#insert operation.   This must move the 
>> node
>> >> if it already exists elsewhere, leaving a reference node in its
>> >> place.    Otherwise, it creates and inserts the node for the bean.
>> >>
>> > What do you mean by moving the node if it is already exist. How to
>> > check if it is the same node ? I don't understand all the details
>> > here. Can you give more information ?
>> >
>> >> Is this what you are suggesting?
>> >>
>> >>        -- Dan
>> >
>> >
>> > Without some use cases, it is difficult to gives exact information but
>> > here are some thoughts on JCR references. This is just to start some
>> > discussions because I don't know if we have to implement the same
>> > features.
>> >
>> > Precondition to map a jcr referenceable node to a bean
>> > 
>> -------------------------------------------------------------------------------- 
>>
>> >
>> > * The referenceable node already exists in the repo (of course based
>> > on mix:referencable).
>> > * If I remember correctly the JCR spec : the reference is stored in a
>> > property in the target node.
>> >
>> > Mapping file
>> > ------------------
>> > We have to check how to specifiy the references in the mapping file.
>> > We should support references from a bean descriptor but also from a
>> > collection descriptor. I mean it should be possible to create a
>> > collection containing some references to other nodes (objects).
>> >
>> > If we accept this situation, we have to find a way to
>> >
>> > 1/ [When retrieving the object containing the reference] : Map a JCR
>> > node property to a java bean and in the case of a collection of
>> > references, a series of JCR node properties into a Java collection (or
>> > map).
>> >
>> > 2/ [When updating, inserting the object containing the reference] :
>> > Map a bean attribute into a JCR property (UUID value) or a collection
>> > attribute into a serie of JCR properties.
>> >
>> > Let me know if I'm wrong because I don't remember all the details from
>> > JCR spec.
>> > We have also to check how to avoid some performance issues (is it
>> > possible to use the existing features like proxy, auto-retrieve,
>> > auto-update, ...).
>> >
>> > Ohoh It is more than I expected 2 days ago :-(
>> >
>> >
>> > Christophe
>> >
>>
>>
>
>


Re: How can aggregation be mapped in OCM?

Posted by Christophe Lombart <ch...@gmail.com>.
Sorry for the delay, I will come back on this mail tommorow. Some
urgent stuffs to do.


Thanks,
Christophe

On 9/5/06, Dan Connelly <ds...@adelphia.net> wrote:
> Christophe
>
> I don't have any fully developed use cases yet, but, yes, there are some
> pre-conditions that I do accept.
>
> In particular, I accept that every model object will have a jcrNodeType
> that has mix:referenceable as a supertype.
>
> For instance:
>
>   <nodeType name="graffito:object" isMixin="false">
>     <supertypes>
>       <supertype>mix:referenceable</supertype>
>       <supertype>nt:unstructured</supertype>
>     </supertypes>
>   </nodeType>
>
> This graffito:object type would be specified as the jcrNodeType of the
> model classes in the ocm mapping.   In addition to that usage, I would
> also have code for persisting references (pointers) using the same
> jcrNodeType.   So, where the parent node is already know, the reference
> node to a bean in that parent can be constructed as follows :
>
>      QueryResult qr = query.execute();   // query criteria based on
> object identity, ie. id="true"
>      NodeIterator matches = qr.getNodes();
>      if ( matches.size() > 0 ) {
>           Node theNode = matches.next();  // take the first one
>           String uuid = theNode.getUUID();   // assume graffito:object
> node type
>           Node refNode = parent.addNode(fieldName,"graffito:object");
>           refNode.setProperty(PersistenceConstant.MUST_DEREFERENCE,
> uuid, PropertyType.REFERENCE);
>      }
>
> An alternative to querying would be to could keep a HashMap associated
> with the JCR Session.   In this HashMap (global for the session), the
> object to persist is the key and its uuid string is the value.   If the
> lookup on the object returns null, then the object has not been inserted
> yet.  Insert it now and record its uuid in the hash map.
>
> Any node in the Repository having a *property* whose name is
> PerstenceConstant.MUST_DEREFERENCE and whose value type is
> PropteryType.REFERENCE should not be used directly.   It should be
> de-referenced through the node with that uuid, regards of the path to
> that node.    De-referencing is node is done as node =
> session.getNodeByUUID(String uuid) and bean converter needs to handle
> all the exceptions that could be thrown by that call.
>
> Pointer chains might exist for multi-step de-referencing.   Maintenance
> of such pointer chains can be a tricky because there is no real
> difference between pointers and data, which is the problem you find in
> the C language.    However, I think that issue is only a small concern
> for my use case(s) and I will defer it.
>
>        -- Dan
>
>
>
> Christophe Lombart wrote:
>
> > On 9/5/06, Dan Connelly <ds...@adelphia.net> wrote:
> >
> >> Christophe:
> >>
> >> Okay.   But it does get a little tricky, as follows:
> >>
> >> ReferencingBeanConverterImpl#insert operation:   This must actually
> >> create a node for the bean if there is no node for its already.   If the
> >> bean has a node (elsewhere),  then a reference node is inserted
> >>
> >
> > If I remember correctly, a referencable node matches to a JCR property
> > in the target node.
> > Why to create subnode ? Sorry if  I'm wrong because I have not all the
> > details on the JCR spec. I have to review it.
> >
> >
> >> ContainedBeanConverterImpl#insert operation.   This must move the node
> >> if it already exists elsewhere, leaving a reference node in its
> >> place.    Otherwise, it creates and inserts the node for the bean.
> >>
> > What do you mean by moving the node if it is already exist. How to
> > check if it is the same node ? I don't understand all the details
> > here. Can you give more information ?
> >
> >> Is this what you are suggesting?
> >>
> >>        -- Dan
> >
> >
> > Without some use cases, it is difficult to gives exact information but
> > here are some thoughts on JCR references. This is just to start some
> > discussions because I don't know if we have to implement the same
> > features.
> >
> > Precondition to map a jcr referenceable node to a bean
> > --------------------------------------------------------------------------------
> >
> > * The referenceable node already exists in the repo (of course based
> > on mix:referencable).
> > * If I remember correctly the JCR spec : the reference is stored in a
> > property in the target node.
> >
> > Mapping file
> > ------------------
> > We have to check how to specifiy the references in the mapping file.
> > We should support references from a bean descriptor but also from a
> > collection descriptor. I mean it should be possible to create a
> > collection containing some references to other nodes (objects).
> >
> > If we accept this situation, we have to find a way to
> >
> > 1/ [When retrieving the object containing the reference] : Map a JCR
> > node property to a java bean and in the case of a collection of
> > references, a series of JCR node properties into a Java collection (or
> > map).
> >
> > 2/ [When updating, inserting the object containing the reference] :
> > Map a bean attribute into a JCR property (UUID value) or a collection
> > attribute into a serie of JCR properties.
> >
> > Let me know if I'm wrong because I don't remember all the details from
> > JCR spec.
> > We have also to check how to avoid some performance issues (is it
> > possible to use the existing features like proxy, auto-retrieve,
> > auto-update, ...).
> >
> > Ohoh It is more than I expected 2 days ago :-(
> >
> >
> > Christophe
> >
>
>


-- 
Best regards,

Christophe

Re: How can aggregation be mapped in OCM?

Posted by Dan Connelly <ds...@adelphia.net>.
Christophe

I don't have any fully developed use cases yet, but, yes, there are some 
pre-conditions that I do accept.   

In particular, I accept that every model object will have a jcrNodeType 
that has mix:referenceable as a supertype.

For instance:

  <nodeType name="graffito:object" isMixin="false">
    <supertypes>
      <supertype>mix:referenceable</supertype>
      <supertype>nt:unstructured</supertype>
    </supertypes>
  </nodeType>   

This graffito:object type would be specified as the jcrNodeType of the 
model classes in the ocm mapping.   In addition to that usage, I would 
also have code for persisting references (pointers) using the same 
jcrNodeType.   So, where the parent node is already know, the reference 
node to a bean in that parent can be constructed as follows :

     QueryResult qr = query.execute();   // query criteria based on 
object identity, ie. id="true"
     NodeIterator matches = qr.getNodes();
     if ( matches.size() > 0 ) {
          Node theNode = matches.next();  // take the first one
          String uuid = theNode.getUUID();   // assume graffito:object 
node type
          Node refNode = parent.addNode(fieldName,"graffito:object");
          refNode.setProperty(PersistenceConstant.MUST_DEREFERENCE, 
uuid, PropertyType.REFERENCE);
     }

An alternative to querying would be to could keep a HashMap associated 
with the JCR Session.   In this HashMap (global for the session), the 
object to persist is the key and its uuid string is the value.   If the 
lookup on the object returns null, then the object has not been inserted 
yet.  Insert it now and record its uuid in the hash map.

Any node in the Repository having a *property* whose name is 
PerstenceConstant.MUST_DEREFERENCE and whose value type is 
PropteryType.REFERENCE should not be used directly.   It should be 
de-referenced through the node with that uuid, regards of the path to 
that node.    De-referencing is node is done as node = 
session.getNodeByUUID(String uuid) and bean converter needs to handle 
all the exceptions that could be thrown by that call.

Pointer chains might exist for multi-step de-referencing.   Maintenance 
of such pointer chains can be a tricky because there is no real 
difference between pointers and data, which is the problem you find in 
the C language.    However, I think that issue is only a small concern 
for my use case(s) and I will defer it.

       -- Dan



Christophe Lombart wrote:

> On 9/5/06, Dan Connelly <ds...@adelphia.net> wrote:
>
>> Christophe:
>>
>> Okay.   But it does get a little tricky, as follows:
>>
>> ReferencingBeanConverterImpl#insert operation:   This must actually
>> create a node for the bean if there is no node for its already.   If the
>> bean has a node (elsewhere),  then a reference node is inserted
>>
>
> If I remember correctly, a referencable node matches to a JCR property
> in the target node.
> Why to create subnode ? Sorry if  I'm wrong because I have not all the
> details on the JCR spec. I have to review it.
>
>
>> ContainedBeanConverterImpl#insert operation.   This must move the node
>> if it already exists elsewhere, leaving a reference node in its
>> place.    Otherwise, it creates and inserts the node for the bean.
>>
> What do you mean by moving the node if it is already exist. How to
> check if it is the same node ? I don't understand all the details
> here. Can you give more information ?
>
>> Is this what you are suggesting?
>>
>>        -- Dan
>
>
> Without some use cases, it is difficult to gives exact information but
> here are some thoughts on JCR references. This is just to start some
> discussions because I don't know if we have to implement the same
> features.
>
> Precondition to map a jcr referenceable node to a bean
> -------------------------------------------------------------------------------- 
>
> * The referenceable node already exists in the repo (of course based
> on mix:referencable).
> * If I remember correctly the JCR spec : the reference is stored in a
> property in the target node.
>
> Mapping file
> ------------------
> We have to check how to specifiy the references in the mapping file.
> We should support references from a bean descriptor but also from a
> collection descriptor. I mean it should be possible to create a
> collection containing some references to other nodes (objects).
>
> If we accept this situation, we have to find a way to
>
> 1/ [When retrieving the object containing the reference] : Map a JCR
> node property to a java bean and in the case of a collection of
> references, a series of JCR node properties into a Java collection (or
> map).
>
> 2/ [When updating, inserting the object containing the reference] :
> Map a bean attribute into a JCR property (UUID value) or a collection
> attribute into a serie of JCR properties.
>
> Let me know if I'm wrong because I don't remember all the details from 
> JCR spec.
> We have also to check how to avoid some performance issues (is it
> possible to use the existing features like proxy, auto-retrieve,
> auto-update, ...).
>
> Ohoh It is more than I expected 2 days ago :-(
>
>
> Christophe
>


Re: How can aggregation be mapped in OCM?

Posted by Christophe Lombart <ch...@gmail.com>.
On 9/5/06, Dan Connelly <ds...@adelphia.net> wrote:
> Christophe:
>
> Okay.   But it does get a little tricky, as follows:
>
> ReferencingBeanConverterImpl#insert operation:   This must actually
> create a node for the bean if there is no node for its already.   If the
> bean has a node (elsewhere),  then a reference node is inserted
>

If I remember correctly, a referencable node matches to a JCR property
in the target node.
Why to create subnode ? Sorry if  I'm wrong because I have not all the
details on the JCR spec. I have to review it.


> ContainedBeanConverterImpl#insert operation.   This must move the node
> if it already exists elsewhere, leaving a reference node in its
> place.    Otherwise, it creates and inserts the node for the bean.
>
What do you mean by moving the node if it is already exist. How to
check if it is the same node ? I don't understand all the details
here. Can you give more information ?

> Is this what you are suggesting?
>
>        -- Dan

Without some use cases, it is difficult to gives exact information but
here are some thoughts on JCR references. This is just to start some
discussions because I don't know if we have to implement the same
features.

Precondition to map a jcr referenceable node to a bean
--------------------------------------------------------------------------------
* The referenceable node already exists in the repo (of course based
on mix:referencable).
* If I remember correctly the JCR spec : the reference is stored in a
property in the target node.

Mapping file
------------------
We have to check how to specifiy the references in the mapping file.
We should support references from a bean descriptor but also from a
collection descriptor. I mean it should be possible to create a
collection containing some references to other nodes (objects).

If we accept this situation, we have to find a way to

1/ [When retrieving the object containing the reference] : Map a JCR
node property to a java bean and in the case of a collection of
references, a series of JCR node properties into a Java collection (or
map).

2/ [When updating, inserting the object containing the reference] :
Map a bean attribute into a JCR property (UUID value) or a collection
attribute into a serie of JCR properties.

Let me know if I'm wrong because I don't remember all the details from JCR spec.
We have also to check how to avoid some performance issues (is it
possible to use the existing features like proxy, auto-retrieve,
auto-update, ...).

Ohoh It is more than I expected 2 days ago :-(


Christophe

Re: How can aggregation be mapped in OCM?

Posted by Dan Connelly <ds...@adelphia.net>.
Christophe:

Okay.   But it does get a little tricky, as follows:

ReferencingBeanConverterImpl#insert operation:   This must actually 
create a node for the bean if there is no node for its already.   If the 
bean has a node (elsewhere),  then a reference node is inserted

ContainedBeanConverterImpl#insert operation.   This must move the node 
if it already exists elsewhere, leaving a reference node in its 
place.    Otherwise, it creates and inserts the node for the bean.

Is this what you are suggesting?

       -- Dan





Christophe Lombart wrote:

> Here are some comments on aggragations, references, ... :
>
>
> 1/ The REFERRENCE feature is not yet supported in the OCM frameworks.
> I think only a new BeanConcerverter impl is required (or maybe almost
> nothing). Any kind of contribution is welcome.
>
> 2/ For aggragation defined in the subnodes, it is possible to use the
> proxy features to maximize performance. As you certainly know, the
> beanConverter and CollectionConverter are there to retrieve, update,
> delete some aggregated objects. You can also disable some actions on
> aggragations (retrieve, insert/update, delete) with the attribtures
> "auto-*).
>
> 3/ There are a BeanConverter impl which gives the Parent Object (of
> course based on the Parent node). See the class
> ParentBeanConverterImpl. There is a small unit test.
>
> Kind regards,
> Christophe
>
>
> On 9/4/06, Dan Connelly <ds...@adelphia.net> wrote:
>
>>
>> Alex:
>>
>> I see that the JCR spec uses the term "Multiple Parents" for roughly the
>> same concept as aggregation.
>>
>> Maybe the problem I am having is somehow due to the fact that the "hard
>> links" support for Multiple Parents, method
>>  addExistingNode(String absPath)
>> in the javax.jcr.Node interface, was dropped from the API (although the
>> spec continues to describe it).
>>
>> The on-line discussion I am finding concerning nodes with "Multiple
>> Parents" says that soft links using a REFERENCE property (or collection
>> element) in all but one parent node is a reasonable substitute for
>> aggregation..    The child's jcr node type must have mix:referenceable
>> supertype.
>>
>> The soft link solution is okay with me, but I see no support for even
>> that in the Graffito jcr mappings.   Am I wrong?
>>
>
>
>
>
>
>> What did you mean by a "custom bean discriptor"?    I am open to any OCM
>> solution but I do not see any features in bean-discriptor that cover
>> REFERENCE as a jcrType.   It is possible that I could use a hack by
>> mapping a bean property as a field-descriptor and then suppling a custom
>> object converter to insert a REFERENCE value in the field's jcr
>> property.    That custom object converter class needs to accommodate any
>> bean class (for my requirements).   This is non-trivial.
>>
>> Also, shared beans are not just bean fields.   They might be elements in
>> a collection.    The single field-descriptor hack does not work in that
>> case.   There  is no jcrNodeType in the collection-descriptor that would
>> force the collection elements to be mapped as  REFERENCE value nodes.
>>
>>        -- Dan
>>
>>
>>
>> Alexandru Popescu wrote:
>>
>> > On 9/3/06, Dan Connelly <ds...@adelphia.net> wrote:
>> >
>> >> How do you express aggregated, not contained, bean references in the
>> >> OCM?
>> >>
>> >> An aggregate bean ref would (presumably) get persisted as a uuid uri,
>> >> not as a content sub-node.    (Path references might be okay 
>> instead of
>> >> uuids.)
>> >>
>> >> If I map naively with two classes that where each has the other as a
>> >> bean element, then pm.insert(rootObj) will traverse this loop
>> >> endlessly.   The rootObj class has proper containment of both these
>> >> mutually referencing classes.
>> >>
>> >
>> > I think you should use a custom bean descriptor to take care of this
>> > kind of mapping.
>> >
>> > ./alex
>> > --
>> > .w( the_mindstorm )p.
>> >
>> >>        -- Dan
>> >>
>> >
>>
>>
>
>


Re: How can aggregation be mapped in OCM?

Posted by Christophe Lombart <ch...@gmail.com>.
Here are some comments on aggragations, references, ... :


1/ The REFERRENCE feature is not yet supported in the OCM frameworks.
I think only a new BeanConcerverter impl is required (or maybe almost
nothing). Any kind of contribution is welcome.

2/ For aggragation defined in the subnodes, it is possible to use the
proxy features to maximize performance. As you certainly know, the
beanConverter and CollectionConverter are there to retrieve, update,
delete some aggregated objects. You can also disable some actions on
aggragations (retrieve, insert/update, delete) with the attribtures
"auto-*).

3/ There are a BeanConverter impl which gives the Parent Object (of
course based on the Parent node). See the class
ParentBeanConverterImpl. There is a small unit test.

Kind regards,
Christophe


On 9/4/06, Dan Connelly <ds...@adelphia.net> wrote:
>
> Alex:
>
> I see that the JCR spec uses the term "Multiple Parents" for roughly the
> same concept as aggregation.
>
> Maybe the problem I am having is somehow due to the fact that the "hard
> links" support for Multiple Parents, method
>  addExistingNode(String absPath)
> in the javax.jcr.Node interface, was dropped from the API (although the
> spec continues to describe it).
>
> The on-line discussion I am finding concerning nodes with "Multiple
> Parents" says that soft links using a REFERENCE property (or collection
> element) in all but one parent node is a reasonable substitute for
> aggregation..    The child's jcr node type must have mix:referenceable
> supertype.
>
> The soft link solution is okay with me, but I see no support for even
> that in the Graffito jcr mappings.   Am I wrong?
>





> What did you mean by a "custom bean discriptor"?    I am open to any OCM
> solution but I do not see any features in bean-discriptor that cover
> REFERENCE as a jcrType.   It is possible that I could use a hack by
> mapping a bean property as a field-descriptor and then suppling a custom
> object converter to insert a REFERENCE value in the field's jcr
> property.    That custom object converter class needs to accommodate any
> bean class (for my requirements).   This is non-trivial.
>
> Also, shared beans are not just bean fields.   They might be elements in
> a collection.    The single field-descriptor hack does not work in that
> case.   There  is no jcrNodeType in the collection-descriptor that would
> force the collection elements to be mapped as  REFERENCE value nodes.
>
>        -- Dan
>
>
>
> Alexandru Popescu wrote:
>
> > On 9/3/06, Dan Connelly <ds...@adelphia.net> wrote:
> >
> >> How do you express aggregated, not contained, bean references in the
> >> OCM?
> >>
> >> An aggregate bean ref would (presumably) get persisted as a uuid uri,
> >> not as a content sub-node.    (Path references might be okay instead of
> >> uuids.)
> >>
> >> If I map naively with two classes that where each has the other as a
> >> bean element, then pm.insert(rootObj) will traverse this loop
> >> endlessly.   The rootObj class has proper containment of both these
> >> mutually referencing classes.
> >>
> >
> > I think you should use a custom bean descriptor to take care of this
> > kind of mapping.
> >
> > ./alex
> > --
> > .w( the_mindstorm )p.
> >
> >>        -- Dan
> >>
> >
>
>


-- 
Best regards,

Christophe

Re: How can aggregation be mapped in OCM?

Posted by Dan Connelly <ds...@adelphia.net>.
Alex:

I see that the JCR spec uses the term "Multiple Parents" for roughly the 
same concept as aggregation.

Maybe the problem I am having is somehow due to the fact that the "hard 
links" support for Multiple Parents, method
 addExistingNode(String absPath)
in the javax.jcr.Node interface, was dropped from the API (although the 
spec continues to describe it).

The on-line discussion I am finding concerning nodes with "Multiple 
Parents" says that soft links using a REFERENCE property (or collection 
element) in all but one parent node is a reasonable substitute for 
aggregation..    The child's jcr node type must have mix:referenceable 
supertype.

The soft link solution is okay with me, but I see no support for even 
that in the Graffito jcr mappings.   Am I wrong?

What did you mean by a "custom bean discriptor"?    I am open to any OCM 
solution but I do not see any features in bean-discriptor that cover 
REFERENCE as a jcrType.   It is possible that I could use a hack by 
mapping a bean property as a field-descriptor and then suppling a custom 
object converter to insert a REFERENCE value in the field's jcr 
property.    That custom object converter class needs to accommodate any 
bean class (for my requirements).   This is non-trivial.

Also, shared beans are not just bean fields.   They might be elements in 
a collection.    The single field-descriptor hack does not work in that 
case.   There  is no jcrNodeType in the collection-descriptor that would 
force the collection elements to be mapped as  REFERENCE value nodes.

       -- Dan



Alexandru Popescu wrote:

> On 9/3/06, Dan Connelly <ds...@adelphia.net> wrote:
>
>> How do you express aggregated, not contained, bean references in the 
>> OCM?
>>
>> An aggregate bean ref would (presumably) get persisted as a uuid uri,
>> not as a content sub-node.    (Path references might be okay instead of
>> uuids.)
>>
>> If I map naively with two classes that where each has the other as a
>> bean element, then pm.insert(rootObj) will traverse this loop
>> endlessly.   The rootObj class has proper containment of both these
>> mutually referencing classes.
>>
>
> I think you should use a custom bean descriptor to take care of this
> kind of mapping.
>
> ./alex
> -- 
> .w( the_mindstorm )p.
>
>>        -- Dan
>>
>


Re: How can aggregation be mapped in OCM?

Posted by Dan Connelly <ds...@adelphia.net>.
I was wrong.   A jcrNodeType and be specified for collection elements in 
the OCM.   

So, it is at least feasible that I could fashion a custom 
ObjectConverter within the current framework that, depending on the OCM, 
will render a bean as either a structure of values or as a REFERENCE.


Re: How can aggregation be mapped in OCM?

Posted by Alexandru Popescu <th...@gmail.com>.
On 9/3/06, Dan Connelly <ds...@adelphia.net> wrote:
> How do you express aggregated, not contained, bean references in the OCM?
>
> An aggregate bean ref would (presumably) get persisted as a uuid uri,
> not as a content sub-node.    (Path references might be okay instead of
> uuids.)
>
> If I map naively with two classes that where each has the other as a
> bean element, then pm.insert(rootObj) will traverse this loop
> endlessly.   The rootObj class has proper containment of both these
> mutually referencing classes.
>

I think you should use a custom bean descriptor to take care of this
kind of mapping.

./alex
--
.w( the_mindstorm )p.

>        -- Dan
>