[hibernate-dev] org.hibernate.persister.spi.PersisterFactory and 5.0

Steve Ebersole steve at hibernate.org
Mon Dec 1 12:28:21 EST 2014


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 at 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 at 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 at 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 at hibernate.org> wrote:
>>>
>>> Hi,
>>>
>>> 2014-11-27 1:23 GMT+01:00 Steve Ebersole <steve at 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/org/hibernate/ogm/jpa/impl/OgmPersisterClassResolver.java
>>> [2]
>>>
>>> https://github.com/hibernate/hibernate-ogm/blob/master/core/src/main/java/org/hibernate/ogm/persister/impl/OgmCollectionPersister.java
>>> [3]
>>>
>>> https://github.com/hibernate/hibernate-ogm/blob/master/core/src/main/java/org/hibernate/ogm/cfg/OgmConfiguration.java
>>>
>>>
>>>
>>> _______________________________________________
>>> 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