As for the "parameter object", I came up with a decent (imo) solution. So
I only wrap the things that are "contextual". Here is the contract right
now:
public interface PersisterFactory extends Service {
/**
* "Parameter object" providing access to additional information that may
be needed
* in the creation of the persisters.
*/
public static interface PersisterCreationContext {
SessionFactoryImplementor getSessionFactory();
Metadata getMetadata();
}
/**
* Create an entity persister instance.
*
* @param entityBinding The mapping information describing the entity
* @param entityCacheAccessStrategy The cache access strategy for the
entity region
* @param naturalIdCacheAccessStrategy The cache access strategy for the
entity's natural-id cross-ref region
* @param creationContext Access to additional information needed to create
an EntityPersister
*
* @return An appropriate entity persister instance.
*
* @throws HibernateException Indicates a problem building the persister.
*/
public EntityPersister createEntityPersister(
PersistentClass entityBinding,
EntityRegionAccessStrategy entityCacheAccessStrategy,
NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy,
PersisterCreationContext creationContext) throws HibernateException;
/**
* Create a collection persister instance.
*
* @param collectionBinding The mapping information describing the
collection
* @param cacheAccessStrategy The cache access strategy for the collection
region
* @param creationContext Access to additional information needed to create
an EntityPersister
*
* @return An appropriate collection persister instance.
*
* @throws HibernateException Indicates a problem building the persister.
*/
public CollectionPersister createCollectionPersister(
Collection collectionBinding,
CollectionRegionAccessStrategy cacheAccessStrategy,
PersisterCreationContext creationContext) throws HibernateException;
}
PersisterCreationContext is the contextual info. And it can be
"statically" defined for each and every call into PersisterFactory. The
other params to #createEntityPersister and #createCollectionPersister are
specific to that call.
On Thu, Nov 27, 2014 at 10:35 AM, Steve Ebersole <steve(a)hibernate.org>
wrote:
Actually, I take that back about Metadata extending
org.hibernate.cfg.Mappings.
I had contemplated doing that, but decided against it since Mappings
exposes all kinds of "extra" stuff that isn't actually mappings/metadata
(config info, contextual info, etc) and I did not want to fuglify these new
contracts that way.
On Thu, Nov 27, 2014 at 10:25 AM, Steve Ebersole <steve(a)hibernate.org>
wrote:
> Well naturally there is still access to all this information :)
>
> IMO SessionFactoryObserver is a hack way of doing this. With 5.0, the
> way to do this would be one of the various bootstrap hooks I mentioned
> earlier. Specifically you want a hook that is called just after all
> metadata is fully known.
>
> BTW, for 5.0 the "metadata" is still using the mappings as defined in the
> org.hibernate.mapping package. So all that code fragment will continue to
> work aside from actually using the Configuration. Interestingly, had
> you used org.hibernate.cfg.Mappings#iterateTables rather than
Configuration#getTableMappings(),
> this code would have continued to work with no changes at all. This is the
> point I made in the initial email about Metadata also being a
> org.hibernate.cfg.Mappings.
>
>
> On Thu, Nov 27, 2014 at 4:36 AM, Emmanuel Bernard <emmanuel(a)hibernate.org
> > wrote:
>
>> To add on Gunnar’s needs
>>
>> 3. Use Configuration to extract physical Table structure
>>
>> We also use configuration in the SchemaDefiner
>> The SchemaDefiner received the Configuration from a custom
>> implementation of SessionFactoryObserver and use it during
>> sessionFactoryCreated.
>>
>> The reason we use Configuration is so that this SchemaDefiner contract
>> can:
>>
>> - access to specific properties (say hibernate.0gm.neo4j.index
>> create-drop )
>> - get information about the table, it’s unique constraints as shown in
>> this pseudo example
>>
>> Iterator<Table> tableMappings = configuration.getTableMappings();
>> while ( tableMappings.hasNext() ) {
>> Table table = tableMappings.next();
>> if ( table.isPhysicalTable() ) {
>> Label label = label( table.getName() );
>> PrimaryKey primaryKey = table.getPrimaryKey();
>> createConstraint( neo4jDb, table, label, primaryKey );
>> @SuppressWarnings("unchecked")
>> Iterator<Column> columnIterator = table.getColumnIterator();
>> while ( columnIterator.hasNext() ) {
>> Column column = columnIterator.next();
>> if ( column.isUnique() ) {
>> createUniqueConstraintIfMissing( neo4jDb, label,
>> column.getName() );
>> }
>> }
>> Iterator<UniqueKey> uniqueKeyIterator =
>> table.getUniqueKeyIterator();
>> while ( uniqueKeyIterator.hasNext() ) {
>> createConstraint( neo4jDb, table, label,
>> uniqueKeyIterator.next() );
>> }
>> }
>> }
>>
>>
>>
>>
>> On 27 Nov 2014, at 10:13, Gunnar Morling <gunnar(a)hibernate.org> wrote:
>>
>> Hi,
>>
>> 2014-11-27 1:23 GMT+01:00 Steve Ebersole <steve(a)hibernate.org>:
>>
>> Part of the goals for ORM 5.0 is moving from Configuration to the
>> ServiceRegistry+Metadata for building a SessionFactory.
>>
>> One of the points I ran into that will have to change
>> is org.hibernate.persister.spi.PersisterFactory. The problems is that
>> PersisterFactory accepts a Configuration as part of building
>> CollectionPersisters. The need for Configuration in the standard
>> CollectionPersister impls is amazingly trivial; we literally use it to
>> locate the associated entity's PersistentClass to grab the classes dom4j
>> node name, and this is right after we have just resolved the
>> corresponding
>> EntityPersister. The point being that the standard CollectionPersisters
>> really don't need access to the Configuration.
>>
>> I am pretty sure OGM provides a custom PersisterFactory, or is it just
>> the PersisterClassResolver that OGM provides? Also, I would assume OGM
>> is
>> providing custom CollectionPersister impls. This change would affect
>> both
>> usages.
>>
>>
>> We don't have a custom PersisterFactory, but there are
>> OgmPersisterClassResolver [1] and OgmCollectionPersister [2]. In the
>> latter
>> we accept a Configuration in the constructor but just pass it to the
>> super
>> 'ctor (AbstractCollectionPersister). We don't do anything ourselves with
>> it.
>>
>>
>> I wanted y'all to be aware of this upcoming change. But I also wanted to
>> start a discussion about what the signature(s) should become. Currently
>> we
>> pass:
>>
>> * Configuration
>> * Collection (the parsed mapping info)
>> * CollectionRegionAccessStrategy
>> * SessionFactoryImplementor
>>
>>
>> I suggest we pass:
>>
>> * Collection
>> * CollectionRegionAccessStrategy
>> * SessionFactoryImplementor
>> * Mapping
>>
>>
>> Should be fine for OGM. I suggest to wrap it into a parameter object
>> ("PersisterInitializationContext" or so). That way stuff can be added
>> down
>> the road without the need to instantly adapt existing persisters.
>>
>> (I changed order to align with the order for building EntityPersisters)
>>
>>
>> Mapping is org.hibernate.engine.spi.Mapping which is part of
>> Configuration. I decided to (at least temporarily) port this contract
>> forward to ease migration. Metadata implements it.
>>
>> There is a similar discussion to be had wrt Integrators. I will follow
>> up
>> with an email specific to them later.
>>
>>
>> Regarding the removal of Configuration in general, there will be some
>> more
>> work to be done in OGM. We have a custom sub-class, OgmConfiguration [3],
>> which is used for two purposes:
>>
>> 1) Set some properties automatically (to enable OGM's naming strategy and
>> query translator etc., use a specific mass indexer for Hibernate Search)
>> 2) Provide an entry point into the API for setting store specific
>> options,
>> e.g. like so:
>>
>> OgmConfiguration ogmCfg = ...;
>> ogmCfg.configureOptionsFor( MongoDB.class )
>> .entity( GolfPlayer.class )
>> .writeConcern( WriteConcernType.REPLICA_ACKNOWLEDGED );
>>
>> We'll need a way to still do 1).
>>
>> 2) is not really required. We provide an alternative anyways, for cases
>> where you don't bootstrap OGM yourself. You can specify a callback class
>> via configuration properties, which then will be invoked and provides the
>> entry point to the fluent API.
>>
>> --Gunnar
>>
>> [1]
>>
>>
https://github.com/hibernate/hibernate-ogm/blob/master/core/src/main/java...
>> [2]
>>
>>
https://github.com/hibernate/hibernate-ogm/blob/master/core/src/main/java...
>> [3]
>>
>>
https://github.com/hibernate/hibernate-ogm/blob/master/core/src/main/java...
>>
>>
>>
>> _______________________________________________
>> hibernate-dev mailing list
>> hibernate-dev(a)lists.jboss.org
>>
https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>
>> _______________________________________________
>> hibernate-dev mailing list
>> hibernate-dev(a)lists.jboss.org
>>
https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>
>>
>>
>