[hibernate-dev] [OGM] Precedence of options specified on different levels

Gunnar Morling gunnar at hibernate.org
Mon Dec 16 05:47:46 EST 2013


2013/12/16 Guillaume SCHEIBEL <guillaume.scheibel at gmail.com>

> My opinion is that each provider "provides" its own set of options. If
> some of them exist in multiple providers they should have the name so we
> won't disturb users.
>

Just to be sure, did you mean to say "... should have the *same* name..."?

Note that the motivations for using OGM include "late backend choice" and
"polyglot persistence" (when possible some day :)), I feel these things are
simpler to achieve when we use the same options across stores where
feasible, so you e.g. don't have to import another AssociationStorage type
when using CouchDB instead of MongoDB.


> My 2 cents :)
> Guillaume
>
>
> 2013/12/16 Gunnar Morling <gunnar at hibernate.org>
>
>> > Only the CouchDB provider in the PR so far. But the idea is to move all
>> to that model.
>>
>> Right; I've a local branch where I had started with @AssociationStorage
>> support for MongoDB, but focused on CouchDB then.
>>
>> On a related note, Emmanuel raised the question whether to use the same
>> option types for different data stores or not, i.e. should we use the same
>> @AssociationStorage annotation and enum for MongoDB and CouchDB?
>>
>> Currently there are the following strategies:
>>
>> * MongoDB: GLOBAL_COLLECTION, COLLECTION, IN_ENTITY
>> * CouchDB: ASSOCIATION_DOCUMENT, IN_ENTITY
>>
>> So we have IN_ENTITY in both, but the other strategies don't directly map
>> to each other. CouchDB doesn't have a notion of "collections", so
>> ASSOCIATION_DOCUMENT is most similar to GLOBAL_COLLECTION from MongoDB
>> (considering the one and only document heap as the "global collection",
>> whereas that maps to a specific "associations" collection for the MongoDB
>> backend).
>>
>> So in a shared enum we might have values like these: IN_ENTITY,
>> ASSOCIATION_DOCUMENT, ASSOCIATION_DOCUMENT_ORGANIZED_BY_ASSOCIATION.
>>
>> The latter would only be supported on MongoDB and raise an exception when
>> used with CouchDB. To make the options usable for other document stores as
>> well, I think we should avoid datastore specific terms such as "collection"
>> in the enum values.
>>
>> As an alternative we could have only IN_ENTITY and ASSOCIATION_DOCUMENT
>> on the shared enum (It seems quite save to assume that this makes sense in
>> every document store). The MongoDB dialect could then provide an additional
>> option which allows to specify the store-specific collection vs. global
>> collection aspect:
>>
>>     @AssociationStorage(ASSOCIATION_DOCUMENT) //shared annotation/enum
>>     @AssociationDocumentStorage(GLOBAL_COLLECTION) //mongo-specific
>> annotation/enum
>>
>> I slightly prefer that last approach because it doesn't expose any
>> specific things on the shared contracts, although increasing the complexity
>> a bit by having two options for MongoDB.
>>
>> --Gunnar
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> 2013/12/16 Emmanuel Bernard <emmanuel at hibernate.org>
>>
>>> Only the CouchDB provider in the PR so far. But the idea is to move all
>>> to that model.
>>>
>>> On Fri 2013-12-13 16:35, Guillaume SCHEIBEL wrote:
>>> > Hi guys,
>>> >
>>> > That sounds nice. Are association storage strategies already using
>>> this new
>>> > feature ?
>>> >
>>> >
>>> > Guillaume
>>> >
>>> >
>>> > 2013/12/13 Emmanuel Bernard <emmanuel at hibernate.org>
>>> >
>>> > > So currently in the pull request, we now have the following
>>> > >
>>> > > 1. property > entity > global
>>> > > 2. for each level in 1., programmatic API beats annotation
>>> > >
>>> > > These are simple rules to understand and all it good.
>>> > >
>>> > > Now Gunnar tried to handle class inheritance, ie superclasses and
>>> > > overridden methods.
>>> > > And we do differ in what we consider the natural rules (or what it
>>> > > should be).
>>> > >
>>> > > Here is how I think the rules should be:
>>> > >
>>> > > 1. property > entity > global
>>> > > 2. for each level in 1., subclass > superclass and overridden method
>>> >
>>> > > parent method
>>> > > 3. for each level (in 1 and 2), programmatic API beats annotation
>>> > >
>>> > > Here is how Gunnar thinks the rules should be:
>>> > >
>>> > > 1. metadata on a class > metadata on a superclass (whether it is on a
>>> > > property or the class)
>>> > > 2. for each hierarchy level, property > entity > global
>>> > > 3. for each level in 1 and 2, programmatic API beats annotation
>>> > >
>>> > > In more concrete words,
>>> > >
>>> > >     @Option(1)
>>> > >     class A {
>>> > >         @Option(2)
>>> > >         public String getMe() {return null;}
>>> > >     }
>>> > >
>>> > >     @Option(3)
>>> > >     class B extends A {
>>> > >         @Override
>>> > >         public String getMe() {return null;}
>>> > >     }
>>> > >
>>> > > In my world, B.getMe has Options(2).
>>> > > In Gunnar's world, B.getMe() has @Option(3).
>>> > >
>>> > > To me, a property level is always more specific than an entity,
>>> hence my
>>> > > interpretation. If someone has set a value on a given property, it
>>> would
>>> > > be dangerous to be "globally" overridden by a subclass.
>>> > >
>>> > > Thoughts?
>>> > >
>>> > > Emmanuel
>>> > >
>>> > > On Tue 2013-12-03 10:48, Gunnar Morling wrote:
>>> > > > Hi,
>>> > > >
>>> > > > In the context of embedded associations for CouchDB [1], I'm
>>> working on
>>> > > > support for configuring the association storage mode using our new
>>> option
>>> > > > system [2]. I can see the following "axes" of configuration here:
>>> > > >
>>> > > > * via annotation
>>> > > >   - on an association property
>>> > > >   - on a type
>>> > > > * via the option API
>>> > > >   - on an association property
>>> > > >   - on a type
>>> > > >   - on the global level
>>> > > > * via a configuration property as given via OgmConfiguration,
>>> > > > persistence.xml etc.
>>> > > > * on super-types
>>> > > >   - via annotations or API
>>> > > >   - on the property or entity level
>>> > > >
>>> > > > I'm looking now for a sensible and comprehensible algorithm for
>>> taking
>>> > > > these sources of configuration into account and determining the
>>> effective
>>> > > > setting for a given association. This could be one way:
>>> > > >
>>> > > > 1) check API
>>> > > >   a) look for a setting given via the programmatic API for the
>>> given
>>> > > > property
>>> > > >   b) if the property is not configured, look for a setting given
>>> for the
>>> > > > entity
>>> > > >   c) if the entity itself is not configured, repeat a) and b)
>>> iteratively
>>> > > > on super-types if present
>>> > > >   d) if no type from the hierarchy is configured look for the
>>> global
>>> > > setting
>>> > > >
>>> > > > 2) check annotations
>>> > > >   if no configuration could be found in 1), do the same for
>>> annotations,
>>> > > > i.e.
>>> > > >   a) look for configuration on the given property
>>> > > >   b) look for configuration on the given entity
>>> > > >   c) repeat a) and b) iteratively on super-types if present
>>> > > >
>>> > > > 3) take default value given via OgmConfiguration/persistence.xml
>>> etc.
>>> > > >
>>> > > > This algorithm ensures that:
>>> > > > * API configuration always takes precedence over annotation
>>> > > configuration;
>>> > > > e.g. if a super-type is configured via the API or the setting is
>>> given on
>>> > > > the API global level, any annotations are ignored
>>> > > > * "More local" configuration takes precedence; i.e. a type's own
>>> > > > configuration wins over configuration from super-types,
>>> property-level
>>> > > > configuration wins over entity-level configuration
>>> > > >
>>> > > > Note that any setting given via OgmConfiguration/persistence.xml
>>> would be
>>> > > > handled as last fallback option, i.e. any configuration given via
>>> > > > annotations or the API would take precedence over that. I first
>>> didn't
>>> > > like
>>> > > > that but I came to think it makes sense, if the property name
>>> conveys
>>> > > that
>>> > > > semantics, e.g. "defaultAssociationStorageMode".
>>> > > >
>>> > > > Any other thoughts or alternative approaches around this?
>>> > > >
>>> > > > Thanks,
>>> > > >
>>> > > > --Gunnar
>>> > > >
>>> > > > [1] https://hibernate.atlassian.net/browse/OGM-389
>>> > > > [1] https://hibernate.atlassian.net/browse/OGM-208
>>> > > > _______________________________________________
>>> > > > hibernate-dev mailing list
>>> > > > hibernate-dev at lists.jboss.org
>>> > > > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>> > > _______________________________________________
>>> > > hibernate-dev mailing list
>>> > > hibernate-dev at lists.jboss.org
>>> > > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>> > >
>>>
>>
>>
>


More information about the hibernate-dev mailing list