incubator-graffito-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alexandru Popescu <the.mindstorm.mailingl...@gmail.com>
Subject Re: OCM - Inheritance & Interface
Date Thu, 16 Feb 2006 16:47:07 GMT
Hi!

Trying to clarify the my proposal: I was questioning what would be the behavior you expect
when the 
following scenario happens:

a class is mapped to a node type X, and the real node to which the action (update or get)
happens 
has a node type Y, where Y is a supertype of X.

Unfortunately this time I could not follow you. The scenarios you are providing are the current

behavior or what you would expect to happen?

Moreover you are making no reference to the node (and its node type) to which the update happens.

The node to which the update happens is given by the path property in the object. I can set
that 
path to wrongly point to another node type. What is happening then?

When talking about updating/fetching we should always talk in terms of object class and node
type.

hth,

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


#: Christophe Lombart changed the world a bit at a time by saying (astral date: 2/16/2006
3:52 PM) :#
> Sorry for the delay, I'm very busy today.
> I'm not sure if I understand correctly all details in your previous mail :-)
> 
> No inheritance
> --------------------
> 
>> allow updating a node whose node type or super node types is X
> Sorry  I don't understand.
> 
> 
> For update :
> ------------------
> I see different use cases (imagine that I have an inheritance tree
> with 2 classes  MyAncestor & MyDescendant).
> 
> 1.   The current situation
> MyDescendant md = // code used to retrieve an object of type MyDescendant.
> persistenceManager.update(md);
> 
> => strict mapping works
> 
> 
> 2. Update with a ancestor based variable which point to a descendant type
> MyAncestor ma = // code used to retrieve an object of node type MyDescendant
> persistenceManager.update(ma);
> 
> => strict mapping works because the referenced object is based on type
> MyDescendant.
> 
> 
> 3. Update with a ancestor based variable which point to an ancestor type.
> MyAncestor ma = //  code used to retrieve an object of node type MyAncestor
> persistenceManager.update(ma);
> 
> => Strict mapping works if MyAncestor class has a matching node type
> 'MyAncestor".
> => of course, if the class MyAncestor is mapped to a node type like
> MyDescendant is doesn't work but it is not an acceptable situation.
> => I'm not if this use cases is used in real application. Generrally,
> ancestor classes are abstract - no ?
> 
> Retrieve
> -----------
> 
> 1. The current situation : strict mapping works
> 
> 2. Retrieve with a ancestor based variable which point to a descendant type
> 
> MyAncestor ma = persistenceManager.getObject("MyAncestor.class",
> "/mydescendant");
> 
> The reference /mydescendant match to the node type "MyDescendant". So,
> the class MyDescendant has to be used instead of MyAncestor. Maybe in
> the case, the getObject API is little bit confused.
> 
> => Strict mapping can be also apply
> 
> 3. Retrieve with a ancestor based variable which point to an ancestor
> type. I think is our current situation.
> 
> => I'm not if this use cases is used in real application. Generrally,
> ancestor classes are abstract - no   ?
> 
> On 2/16/06, Alexandru Popescu <the.mindstorm.mailinglist@gmail.com> wrote:
>> Hi!
>>
>> I have finally got confused :-), and I would like to hear your opinion on the following
points.
>>
>> A] Updates
>>
>> 1/ NO INHERITANCE DEFINED
>>
>> Would it be allowed for an object mapped to node type X to update a node whose node
type or super
>> node types is X? or should it be a strict mapping? (an object mapped to node type
X should be
>> allowed to update a node only if the node type is X).
>>
>> My opinion: first approach (allow updating a node whose node type or super node types
is X)
>>
>> 2/ NODETYPE_PER_CONCRETECLASS
>>
>> Same question as above.
>>
>> My opinion: same as above
>>
>> 3/ NODETYPE_PER_HIERARCHY
>>
>> Same question as above.
>>
>> My opinion: same as above.
>>
>> _Conclusion_: in terms of updates the behavior would be the same disregarding if
inheritance.
>>
>> B] Fetching (getObject)
>>
>> 1/ NO INHERITANCE DEFINED
>>
>> Would it be allowed to fetch an object mapped to node type X from a node whose node
type or one of
>> its super node types is X? or should it be a strict relation? (an object mapped to
node type X
>> should be accesible only from a node with node type X)
>>
>> My opinion: first approach
>>
>> 2/ NODETYPE_PER_CONCRETECLASS
>>
>> Same question as above.
>>
>> My opinion: same as above.
>>
>> 3/ NODETYPE_PER_HIERARCHY
>>
>> Same question as above.
>>
>> My opinion: same as above.
>>
>> _Conclusion_: in terms of retrieval the behavior would be the same disregarding if
inheritance.
>>
>> At a first glance, having the same behavior when inheritance is involved or not may
look quite
>> weird. Still, thinking in terms of Liskov principle about node type hierarchy, I
would say that
>> things look more clear.
>>
>> Please let me know what do you think about this.
>>
>> tia,
>>
>> ./alex
>> --
>> .w( the_mindstorm )p.
>>
>> #: Alexandru Popescu changed the world a bit at a time by saying (astral date: 2/10/2006
2:19 PM) :#
>> > Hi!
>> >
>> > Here is my proposal for handling inheritance:
>> >
>> > 1/ Node type per class hierarchy
>> >
>> > Scenario: all hierarchy classes are using the same node type for persistence.
This strategy is
>> > covering scenarios where nt:unstructured or some other very generic node type
is used for persisting
>> >   a hierachy of classes.
>> >
>> > Inheritance behaves normally: all subclasses are inheritting properties/nodes
from their parent classes.
>> >
>> > Note: To differentiate between the classes the mapping should define a discriminator
property: a
>> > property that determines what the real type of the corresponding object in hierarchy.
Without this
>> > requirement, queries cannot be performed.
>> >
>> > Constraint: if the node type has mandatory properties/nodes, than these must
be mapped. Otherwise,
>> > the storage will not work.
>> >
>> > Example:
>> >
>> > As a quick example thing about the scenario where People is extendend by Student
and Teacher
>> > classes, and both Student and Teacher are persisted using a node type: nt:people.
>> >
>> > 2/ Node type per subclass
>> >
>> > Scenario: each non-abstract subclass is using its own node type for persistence.
This strategy is
>> > covering scenarios where very specific node types are used for mapping real
classes.
>> >
>> > Details: there are no visible problems/constraints regarding this scenario.
Inheritance behavses
>> > normally: all subclasses are inheritting properties/nodes from their parent
classes.
>> >
>> > Constraint: the parent node under which the subtree of these classes is hosted
must be generic
>> > enough to support different node types (f.e. nt:unstructured).
>> >
>> > 3/ Implicit/Explicit polymorphic queries
>> >
>> > As Marcel Reutegger (Jackrabbit committer) pointed: according to section 6.6.3.2
of the JCR spec:
>> >
>> > A type constraint specifies the common primary node type of the returned
>> > nodes, plus, possibly, additional mixin types that they also must have.
>> > Type constraints are inheritance-sensitive in that specifying a
>> > constraint of node type X will include all nodes explicitly declared to
>> > be type X, as well as all nodes of subtypes of X.
>> >
>> > Translating this in Java hierarchies:
>> >
>> > when searching for an object type X, than the query will return by default all
nodes of type X or
>> > any subtype of X.
>> >
>> >
>> > For the "node per class hierarchy" strategy this will use the discriminator
property value to
>> > instantiate the correct subtypes of X. Without the discriminator property, there
is no possible
>> > solution to identify the correct subtype of X to be instantiated.
>> >
>> > For the "node per subclass" strategy this will use the union of all node types
corresponding to the
>> > X and all its subclasses.
>> >
>> > Note: the same strategy can be applied to search using interfaces.
>> >
>> > Explicit polymorhic query:
>> >
>> > However, there are cases when explicit polymorphic queries should be used. In
this case, querying
>> > for a type X will return only nodes corresponding to X class, disregarding any
nodes that map to a
>> > subclass of X.
>> >
>> > For the "node per class hierarchy" strategy this would suppose searching for
nodes type
>> > corresponding to the specified hierarchy and for discriminator="condition to
match only type Y"
>> >
>> > For the "node per subsclass" strategy this would suppose searching for nodes
having the node type
>> > exactly matching the class, dismissing any nodes that correspond to possible
subtypes.
>> >
>> > Supporting all these behavior in mapping would imply:
>> > - creating special mappings support for the 2 strategies (node type per class
hierarchy and node
>> > type per subclass)
>> > - adding an attribute specifying what is the polymorphic behavior: implicit
or explicit.
>> >
>> > In my opinion this proposal covers a wide range of scenarios, hopefully all.
Please take your time
>> > to think about it and feel free to find missing points :-).
>> >
>> > cheers,
>> >
>> > ./alex
>> > --
>> > .w( the_mindstorm )p.
>> >
>> > ps: I must give credit for the inspiration and some good ideas to Hibernate
guys and all other
>> > contributers to ORM tools.
>> >
>>
>>
> 
> 
> --
> Best regards,
> 
> Christophe
> 


Mime
View raw message