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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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
>





Reply via email to