HHH-6110 : Integrate new metamodel into persisters

This commit is contained in:
Gail Badner 2011-05-24 13:53:21 -07:00
parent 6a3d4dc4ca
commit 86ddbc09d9
10 changed files with 243 additions and 8 deletions

View File

@ -112,6 +112,8 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.source.spi.MetadataImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
@ -502,6 +504,47 @@ public final class SessionFactoryImpl
this.observer.sessionFactoryCreated( this );
}
public SessionFactoryImpl(
MetadataImplementor metadata,
Mapping mapping,
ServiceRegistry serviceRegistry,
SessionFactoryObserver observer) throws HibernateException {
LOG.debug( "Building session factory" );
// TODO: remove initialization of final variables; just setting to null to make compiler happy
this.name = null;
this.uuid = null;
this.entityPersisters = null;
this.classMetadata = null;
this.collectionPersisters = null;
this.collectionMetadata = null;
this.collectionRolesByEntityParticipant = null;
this.identifierGenerators = null;
this.namedQueries = null;
this.namedSqlQueries = null;
this.sqlResultSetMappings = null;
this.filters = null;
this.fetchProfiles = null;
this.imports = null;
this.interceptor = null;
this.serviceRegistry = null;
this.settings = null;
this.properties = null;
this.queryCache = null;
this.updateTimestampsCache = null;
this.queryCaches = null;
this.currentSessionContext = null;
this.entityNotFoundDelegate = null;
this.sqlFunctionRegistry = null;
this.queryPlanCache = null;
this.typeResolver = null;
this.typeHelper = null;
this.transactionEnvironment = null;
// TODO: implement
}
public Session openSession() throws HibernateException {
return withOptions().openSession();
}

View File

@ -71,7 +71,7 @@ public class FilterDefBinder {
for ( AnnotationInstance prm : JandexHelper.getValueAsArray( filterDef, "parameters" ) ) {
prms.put(
JandexHelper.getValueAsString( prm, "name" ),
metadata.typeResolver().heuristicType( JandexHelper.getValueAsString( prm, "type" ) )
metadata.getTypeResolver().heuristicType( JandexHelper.getValueAsString( prm, "type" ) )
);
}
metadata.addFilterDef(

View File

@ -112,6 +112,11 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
filterDefs.put(def.getFilterName(), def);
}
public Map<String, FilterDefinition> getFilterDefinitions() {
return filterDefs;
}
public void addIdGenerator( IdGenerator generator ) {
idGenerators.put(generator.getName(), generator);
}
@ -263,7 +268,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
return fetchProfiles.values();
}
public TypeResolver typeResolver() {
public TypeResolver getTypeResolver() {
return typeResolver;
}
}

View File

@ -23,12 +23,16 @@
*/
package org.hibernate.metamodel.source.spi;
import java.util.Map;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.relational.Database;
import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.type.TypeResolver;
/**
* @author Steve Ebersole
@ -40,6 +44,10 @@ public interface MetadataImplementor extends Metadata {
public Iterable<EntityBinding> getEntityBindings();
public EntityBinding getEntityBinding(String entityName);
public TypeResolver getTypeResolver();
public Map<String, FilterDefinition> getFilterDefinitions();
public void addImport(String entityName, String entityName1);
public void addEntity(EntityBinding entityBinding);

View File

@ -32,6 +32,8 @@ import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.spi.PersisterClassResolver;
@ -62,6 +64,21 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
Mapping.class
};
/**
* The constructor signature for {@link EntityPersister} implementations using
* an {@link EntityBinding}.
*
* @todo make EntityPersister *not* depend on {@link SessionFactoryImplementor} if possible.
* @todo change ENTITY_PERSISTER_CONSTRUCTOR_ARGS_NEW to ENTITY_PERSISTER_CONSTRUCTOR_ARGS
* when new metamodel is integrated
*/
public static final Class[] ENTITY_PERSISTER_CONSTRUCTOR_ARGS_NEW = new Class[] {
EntityBinding.class,
EntityRegionAccessStrategy.class,
SessionFactoryImplementor.class,
Mapping.class
};
/**
* The constructor signature for {@link CollectionPersister} implementations
*
@ -75,6 +92,22 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
SessionFactoryImplementor.class
};
/**
* The constructor signature for {@link CollectionPersister} implementations using
* a {@link PluralAttributeBinding}
*
* @todo still need to make collection persisters EntityMode-aware
* @todo make EntityPersister *not* depend on {@link SessionFactoryImplementor} if possible.
* @todo change COLLECTION_PERSISTER_CONSTRUCTOR_ARGS_NEW to COLLECTION_PERSISTER_CONSTRUCTOR_ARGS
* when new metamodel is integrated
*/
private static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS_NEW = new Class[] {
PluralAttributeBinding.class,
CollectionRegionAccessStrategy.class,
Configuration.class,
SessionFactoryImplementor.class
};
private ServiceRegistryImplementor serviceRegistry;
@Override
@ -93,17 +126,32 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
if ( persisterClass == null ) {
persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getEntityPersisterClass( metadata );
}
return create( persisterClass, metadata, cacheAccessStrategy, factory, cfg );
return create( persisterClass, ENTITY_PERSISTER_CONSTRUCTOR_ARGS, metadata, cacheAccessStrategy, factory, cfg );
}
@Override
@SuppressWarnings( {"unchecked"})
public EntityPersister createEntityPersister(EntityBinding metadata,
EntityRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory,
Mapping cfg) {
Class<? extends EntityPersister> persisterClass = metadata.getEntityPersisterClass();
if ( persisterClass == null ) {
persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getEntityPersisterClass( metadata );
}
return create( persisterClass, ENTITY_PERSISTER_CONSTRUCTOR_ARGS_NEW, metadata, cacheAccessStrategy, factory, cfg );
}
// TODO: change metadata arg type to EntityBinding when new metadata is integrated
private static EntityPersister create(
Class<? extends EntityPersister> persisterClass,
PersistentClass metadata,
Class[] persisterConstructorArgs,
Object metadata,
EntityRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory,
Mapping cfg) throws HibernateException {
try {
Constructor<? extends EntityPersister> constructor = persisterClass.getConstructor( ENTITY_PERSISTER_CONSTRUCTOR_ARGS );
Constructor<? extends EntityPersister> constructor = persisterClass.getConstructor( persisterConstructorArgs );
try {
return constructor.newInstance( metadata, cacheAccessStrategy, factory, cfg );
}
@ -143,17 +191,34 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getCollectionPersisterClass( metadata );
}
return create( persisterClass, cfg, metadata, cacheAccessStrategy, factory );
return create( persisterClass, COLLECTION_PERSISTER_CONSTRUCTOR_ARGS, cfg, metadata, cacheAccessStrategy, factory );
}
@Override
@SuppressWarnings( {"unchecked"})
public CollectionPersister createCollectionPersister(Configuration cfg,
PluralAttributeBinding metadata,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException {
Class<? extends CollectionPersister> persisterClass = metadata.getCollectionPersisterClass();
if ( persisterClass == null ) {
persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getCollectionPersisterClass( metadata );
}
return create( persisterClass, COLLECTION_PERSISTER_CONSTRUCTOR_ARGS_NEW, cfg, metadata, cacheAccessStrategy, factory );
}
// TODO: change metadata arg type to PluralAttributeBinding when new metadata is integrated
private static CollectionPersister create(
Class<? extends CollectionPersister> persisterClass,
Class[] persisterConstructorArgs,
Configuration cfg,
Collection metadata,
Object metadata,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException {
try {
Constructor<? extends CollectionPersister> constructor = persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
Constructor<? extends CollectionPersister> constructor = persisterClass.getConstructor( persisterConstructorArgs );
try {
return constructor.newInstance( metadata, cacheAccessStrategy, cfg, factory );
}

View File

@ -28,6 +28,8 @@ import org.hibernate.mapping.JoinedSubclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.UnionSubclass;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.collection.BasicCollectionPersister;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.collection.OneToManyPersister;
@ -42,6 +44,28 @@ import org.hibernate.persister.spi.UnknownPersisterException;
* @author Steve Ebersole
*/
public class StandardPersisterClassResolver implements PersisterClassResolver {
public Class<? extends EntityPersister> getEntityPersisterClass(EntityBinding metadata) {
// todo : make sure this is based on an attribute kept on the metamodel in the new code, not the concrete PersistentClass impl found!
switch ( metadata.getInheritanceType() ) {
case JOINED: {
joinedSubclassEntityPersister();
}
case SINGLE_TABLE: {
return singleTableEntityPersister();
}
case TABLE_PER_CLASS: {
return unionSubclassEntityPersister();
}
default: {
throw new UnknownPersisterException(
"Could not determine persister implementation for entity [" + metadata.getEntity().getName() + "]"
);
}
}
}
@Override
public Class<? extends EntityPersister> getEntityPersisterClass(PersistentClass metadata) {
// todo : make sure this is based on an attribute kept on the metamodel in the new code, not the concrete PersistentClass impl found!
@ -78,6 +102,11 @@ public class StandardPersisterClassResolver implements PersisterClassResolver {
return metadata.isOneToMany() ? oneToManyPersister() : basicCollectionPersister();
}
@Override
public Class<? extends CollectionPersister> getCollectionPersisterClass(PluralAttributeBinding metadata) {
return metadata.getCollectionElement().isOneToMany() ? oneToManyPersister() : basicCollectionPersister();
}
private Class<OneToManyPersister> oneToManyPersister() {
return OneToManyPersister.class;
}

View File

@ -25,6 +25,8 @@ package org.hibernate.persister.spi;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.Service;
@ -50,6 +52,16 @@ public interface PersisterClassResolver extends Service {
*/
Class<? extends EntityPersister> getEntityPersisterClass(PersistentClass metadata);
/**
* Returns the entity persister class for a given entityName or null
* if the entity persister class should be the default.
*
* @param metadata The entity metadata
*
* @return The entity persister class to use
*/
Class<? extends EntityPersister> getEntityPersisterClass(EntityBinding metadata);
/**
* Returns the collection persister class for a given collection role or null
* if the collection persister class should be the default.
@ -59,4 +71,14 @@ public interface PersisterClassResolver extends Service {
* @return The collection persister class to use
*/
Class<? extends CollectionPersister> getCollectionPersisterClass(Collection metadata);
/**
* Returns the collection persister class for a given collection role or null
* if the collection persister class should be the default.
*
* @param metadata The collection metadata
*
* @return The collection persister class to use
*/
Class<? extends CollectionPersister> getCollectionPersisterClass(PluralAttributeBinding metadata);
}

View File

@ -31,6 +31,8 @@ import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.Service;
@ -69,6 +71,24 @@ public interface PersisterFactory extends Service {
SessionFactoryImplementor factory,
Mapping cfg) throws HibernateException;
/**
* Create an entity persister instance.
*
* @param model The O/R mapping metamodel definition for the entity
* @param cacheAccessStrategy The caching strategy for this entity
* @param factory The session factory
* @param cfg The overall mapping
*
* @return An appropriate entity persister instance.
*
* @throws HibernateException Indicates a problem building the persister.
*/
public EntityPersister createEntityPersister(
EntityBinding model,
EntityRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory,
Mapping cfg) throws HibernateException;
/**
* Create a collection persister instance.
*
@ -86,4 +106,23 @@ public interface PersisterFactory extends Service {
Collection model,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException;
/**
* Create a collection persister instance.
*
* @param cfg The configuration
* @param model The O/R mapping metamodel definition for the collection
* @param cacheAccessStrategy The caching strategy for this collection
* @param factory The session factory
*
* @return An appropriate collection persister instance.
*
* @throws HibernateException Indicates a problem building the persister.
*/
public CollectionPersister createCollectionPersister(
Configuration cfg,
PluralAttributeBinding model,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException;
}

View File

@ -45,6 +45,8 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
@ -62,11 +64,21 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
return NoopEntityPersister.class;
}
@Override
public Class<? extends EntityPersister> getEntityPersisterClass(EntityBinding metadata) {
return NoopEntityPersister.class;
}
@Override
public Class<? extends CollectionPersister> getCollectionPersisterClass(Collection metadata) {
return NoopCollectionPersister.class;
}
@Override
public Class<? extends CollectionPersister> getCollectionPersisterClass(PluralAttributeBinding metadata) {
return NoopCollectionPersister.class;
}
public static class NoopEntityPersister implements EntityPersister {
public NoopEntityPersister(org.hibernate.mapping.PersistentClass persistentClass,

View File

@ -44,6 +44,8 @@ import org.hibernate.id.IdentifierGenerator;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.internal.PersisterClassResolverInitiator;
import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.persister.collection.CollectionPersister;
@ -78,10 +80,20 @@ public class PersisterClassProviderTest extends junit.framework.TestCase {
return GoofyProvider.class;
}
@Override
public Class<? extends EntityPersister> getEntityPersisterClass(EntityBinding metadata) {
return GoofyProvider.class;
}
@Override
public Class<? extends CollectionPersister> getCollectionPersisterClass(Collection metadata) {
return null;
}
@Override
public Class<? extends CollectionPersister> getCollectionPersisterClass(PluralAttributeBinding metadata) {
return null;
}
}
public static class GoofyProvider implements EntityPersister {