From ddfcc44d760938578771cb6ce24c809c980c8b8b Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 4 Mar 2011 15:36:07 -0600 Subject: [PATCH] HHH-5916 - Add support for a programmatic way to define a default EntityPersister and CollectionPersister class implementation --- .../cfg/AnnotationConfiguration.java | 28 --- .../java/org/hibernate/cfg/Configuration.java | 34 +--- .../java/org/hibernate/cfg/HbmBinder.java | 30 --- .../main/java/org/hibernate/cfg/Mappings.java | 11 -- .../cfg/annotations/CollectionBinder.java | 13 -- .../cfg/annotations/EntityBinder.java | 10 - .../hibernate/impl/SessionFactoryImpl.java | 18 +- .../persister/PersisterClassProvider.java | 47 ----- .../hibernate/persister/PersisterFactory.java | 177 ----------------- .../PersisterClassResolverInitiator.java | 69 +++++++ .../internal/PersisterFactoryImpl.java | 183 ++++++++++++++++++ .../internal/PersisterFactoryInitiator.java | 69 +++++++ .../StandardPersisterClassResolver.java | 88 +++++++++ .../persister/spi/PersisterClassResolver.java | 54 ++++++ .../persister/spi/PersisterFactory.java | 89 +++++++++ .../spi/UnknownPersisterException.java | 41 ++++ .../spi/StandardServiceInitiators.java | 5 + .../GoofyPersisterClassProvider.java | 11 +- .../persister/PersisterClassProviderTest.java | 5 +- .../org/hibernate/ejb/AvailableSettings.java | 2 +- .../org/hibernate/ejb/Ejb3Configuration.java | 18 -- .../PersisterClassProviderTest.java | 16 +- 22 files changed, 633 insertions(+), 385 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/persister/PersisterClassProvider.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/persister/PersisterFactory.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryInitiator.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterClassResolver.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/spi/UnknownPersisterException.java diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java index 0195d31f3e..07cb7e0fab 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java @@ -26,37 +26,15 @@ package org.hibernate.cfg; import java.io.File; import java.io.InputStream; import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Properties; -import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.persistence.MapsId; import org.dom4j.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.hibernate.AnnotationException; -import org.hibernate.DuplicateMappingException; import org.hibernate.HibernateException; import org.hibernate.Interceptor; import org.hibernate.MappingException; -import org.hibernate.annotations.AnyMetaDef; -import org.hibernate.annotations.common.reflection.ReflectionManager; -import org.hibernate.annotations.common.reflection.XClass; -import org.hibernate.engine.NamedQueryDefinition; -import org.hibernate.engine.NamedSQLQueryDefinition; -import org.hibernate.engine.ResultSetMappingDefinition; -import org.hibernate.mapping.IdGenerator; -import org.hibernate.mapping.Join; -import org.hibernate.mapping.PersistentClass; -import org.hibernate.mapping.Table; -import org.hibernate.persister.PersisterClassProvider; -import org.hibernate.util.CollectionHelper; /** * Similar to the {@link Configuration} object but handles EJB3 and Hibernate @@ -264,12 +242,6 @@ public class AnnotationConfiguration extends Configuration { return this; } - @Override - public AnnotationConfiguration setPersisterClassProvider(PersisterClassProvider persisterClassProvider) { - super.setPersisterClassProvider( persisterClassProvider ); - return this; - } - @Deprecated protected class ExtendedMappingsImpl extends MappingsImpl implements ExtendedMappings { } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java index ba64ce4900..e239c6b870 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java @@ -94,7 +94,6 @@ import org.hibernate.engine.Mapping; import org.hibernate.engine.NamedQueryDefinition; import org.hibernate.engine.NamedSQLQueryDefinition; import org.hibernate.engine.ResultSetMappingDefinition; -import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.event.AutoFlushEventListener; import org.hibernate.event.DeleteEventListener; import org.hibernate.event.DirtyCheckEventListener; @@ -150,7 +149,6 @@ import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.mapping.TypeDef; import org.hibernate.mapping.UniqueKey; -import org.hibernate.persister.PersisterClassProvider; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.secure.JACCConfiguration; import org.hibernate.service.spi.ServiceRegistry; @@ -261,7 +259,6 @@ public class Configuration implements Serializable { protected transient XMLHelper xmlHelper; protected NamingStrategy namingStrategy; - private PersisterClassProvider persisterClassProvider; private SessionFactoryObserver sessionFactoryObserver; private EventListeners eventListeners; @@ -359,7 +356,6 @@ public class Configuration implements Serializable { propertyRefResolver = new HashMap(); caches = new ArrayList(); namingStrategy = EJB3NamingStrategy.INSTANCE; - persisterClassProvider = null; setEntityResolver( new EJB3DTDEntityResolver() ); anyMetaDefs = new HashMap(); propertiesAnnotatedWithMapsId = new HashMap>(); @@ -1999,7 +1995,7 @@ public class Configuration implements Serializable { /** * Set the current {@link Interceptor} * - * @param interceptor The {@link Interceptor} to use for the {@link #buildSessionFactory() built} + * @param interceptor The {@link Interceptor} to use for the {@link #buildSessionFactory) built} * {@link SessionFactory}. * * @return this for method chaining @@ -2866,26 +2862,6 @@ public class Configuration implements Serializable { return this; } - public PersisterClassProvider getPersisterClassProvider() { - return persisterClassProvider; - } - - /** - * Defines a custom persister class provider. - * - * The persister class is chosen according to the following rules in decreasing priority: - * - the persister class defined explicitly via annotation or XML - * - the persister class returned by the PersisterClassProvider implementation (if not null) - * - the default provider as chosen by Hibernate Core (best choice most of the time) - * - * - * @param persisterClassProvider implementation - */ - public Configuration setPersisterClassProvider(PersisterClassProvider persisterClassProvider) { - this.persisterClassProvider = persisterClassProvider; - return this; - } - /** * Retrieve the IdentifierGeneratorFactory in effect for this configuration. * @@ -3118,14 +3094,6 @@ public class Configuration implements Serializable { Configuration.this.namingStrategy = namingStrategy; } - public PersisterClassProvider getPersisterClassProvider() { - return persisterClassProvider; - } - - public void setPersisterClassProvider(PersisterClassProvider persisterClassProvider) { - Configuration.this.persisterClassProvider = persisterClassProvider; - } - public TypeResolver getTypeResolver() { return typeResolver; } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java index 473fc0b47b..e93dd0e60c 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java @@ -87,9 +87,6 @@ import org.hibernate.mapping.UnionSubclass; import org.hibernate.mapping.UniqueKey; import org.hibernate.mapping.Value; import org.hibernate.mapping.FetchProfile; -import org.hibernate.persister.PersisterClassProvider; -import org.hibernate.persister.collection.CollectionPersister; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.JoinedSubclassEntityPersister; import org.hibernate.persister.entity.SingleTableEntityPersister; import org.hibernate.persister.entity.UnionSubclassEntityPersister; @@ -690,9 +687,6 @@ public final class HbmBinder { entity.setMetaAttributes( getMetas( node, inheritedMetas ) ); // PERSISTER - //persister node in XML has priority over - //persisterClassProvider - //if all fail, the default Hibernate persisters kick in Attribute persisterNode = node.attribute( "persister" ); if ( persisterNode != null ) { try { @@ -704,17 +698,6 @@ public final class HbmBinder { + persisterNode.getValue() ); } } - else { - final PersisterClassProvider persisterClassProvider = mappings.getPersisterClassProvider(); - if ( persisterClassProvider != null ) { - final Class persister = persisterClassProvider.getEntityPersisterClass( - entity.getEntityName() - ); - if ( persister != null ) { - entity.setEntityPersisterClass( persister ); - } - } - } // CUSTOM SQL handleCustomSQL( node, entity ); @@ -1416,9 +1399,6 @@ public final class HbmBinder { // PERSISTER - //persister node in XML has priority over - //persisterClassProvider - //if all fail, the default Hibernate persisters kick in Attribute persisterNode = node.attribute( "persister" ); if ( persisterNode != null ) { try { @@ -1430,16 +1410,6 @@ public final class HbmBinder { + persisterNode.getValue() ); } } - else { - final PersisterClassProvider persisterClassProvider = mappings.getPersisterClassProvider(); - if ( persisterClassProvider != null ) { - final Class persister = - persisterClassProvider.getCollectionPersisterClass( collection.getRole() ); - if ( persister != null ) { - collection.setCollectionPersisterClass( persister ); - } - } - } Attribute typeNode = node.attribute( "collection-type" ); if ( typeNode != null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Mappings.java b/hibernate-core/src/main/java/org/hibernate/cfg/Mappings.java index 7886b3f777..3e3bb128dd 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Mappings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Mappings.java @@ -51,7 +51,6 @@ import org.hibernate.mapping.TypeDef; import org.hibernate.mapping.AuxiliaryDatabaseObject; import org.hibernate.mapping.Column; import org.hibernate.mapping.FetchProfile; -import org.hibernate.persister.PersisterClassProvider; import org.hibernate.type.TypeResolver; /** @@ -90,16 +89,6 @@ public interface Mappings { */ public void setNamingStrategy(NamingStrategy namingStrategy); - /** - * Get the current persister class provider implementation - */ - public PersisterClassProvider getPersisterClassProvider(); - - /** - * Set the current persister class provider implementation - */ - public void setPersisterClassProvider(PersisterClassProvider persisterClassProvider); - /** * Returns the currently bound default schema name. * diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java index 2922fc1203..e5cd290d93 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java @@ -111,7 +111,6 @@ import org.hibernate.mapping.Selectable; import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.SingleTableSubclass; import org.hibernate.mapping.Table; -import org.hibernate.persister.PersisterClassProvider; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.util.StringHelper; @@ -402,22 +401,10 @@ public abstract class CollectionBinder { OptimisticLock lockAnn = property.getAnnotation( OptimisticLock.class ); if ( lockAnn != null ) collection.setOptimisticLocked( !lockAnn.excluded() ); - //@Persister has priority over PersisterClassProvider - //if all fail, left null and Hibernate defaults kick in Persister persisterAnn = property.getAnnotation( Persister.class ); if ( persisterAnn != null ) { collection.setCollectionPersisterClass( persisterAnn.impl() ); } - else { - final PersisterClassProvider persisterClassProvider = mappings.getPersisterClassProvider(); - if (persisterClassProvider != null) { - final Class persister = - persisterClassProvider.getCollectionPersisterClass( collection.getRole() ); - if (persister != null) { - collection.setCollectionPersisterClass( persister ); - } - } - } // set ordering if ( orderBy != null ) collection.setOrderBy( orderBy ); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java index e0c988cf9a..fe0daf3e4d 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java @@ -83,7 +83,6 @@ import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.mapping.TableOwner; import org.hibernate.mapping.Value; -import org.hibernate.persister.PersisterClassProvider; import org.hibernate.util.ReflectHelper; import org.hibernate.util.StringHelper; @@ -251,9 +250,6 @@ public class EntityBinder { persistentClass.setSelectBeforeUpdate( selectBeforeUpdate ); //set persister if needed - //@Persister has precedence over @Entity.persister - //in both fail we look for the PersisterClassProvider - //if all fail, the persister is left null and the Hibernate defaults kick in Persister persisterAnn = annotatedClass.getAnnotation( Persister.class ); Class persister = null; if ( persisterAnn != null ) { @@ -269,12 +265,6 @@ public class EntityBinder { throw new AnnotationException( "Could not find persister class: " + persister ); } } - else { - final PersisterClassProvider persisterClassProvider = mappings.getPersisterClassProvider(); - if ( persisterClassProvider != null ) { - persister = persisterClassProvider.getEntityPersisterClass( persistentClass.getEntityName() ); - } - } } if ( persister != null ) { persistentClass.setEntityPersisterClass( persister ); diff --git a/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java index 3a7dedf62d..323bfcf835 100644 --- a/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java @@ -80,11 +80,12 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.RootClass; import org.hibernate.metadata.ClassMetadata; import org.hibernate.metadata.CollectionMetadata; -import org.hibernate.persister.PersisterFactory; +import org.hibernate.persister.internal.PersisterFactoryImpl; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.Queryable; +import org.hibernate.persister.spi.PersisterFactory; import org.hibernate.pretty.MessageHelper; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.service.jdbc.connections.spi.ConnectionProvider; @@ -109,7 +110,6 @@ import org.slf4j.LoggerFactory; import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.StringRefAddr; -import javax.transaction.TransactionManager; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInputStream; @@ -289,7 +289,12 @@ public final class SessionFactoryImpl allCacheRegions.put( cacheRegionName, entityRegion ); } } - EntityPersister cp = PersisterFactory.createClassPersister( model, accessStrategy, this, mapping ); + EntityPersister cp = serviceRegistry.getService( PersisterFactory.class ).createEntityPersister( + model, + accessStrategy, + this, + mapping + ); entityPersisters.put( model.getEntityName(), cp ); classMeta.put( model.getEntityName(), cp.getClassMetadata() ); } @@ -310,7 +315,12 @@ public final class SessionFactoryImpl entityAccessStrategies.put( cacheRegionName, accessStrategy ); allCacheRegions.put( cacheRegionName, collectionRegion ); } - CollectionPersister persister = PersisterFactory.createCollectionPersister( cfg, model, accessStrategy, this) ; + CollectionPersister persister = serviceRegistry.getService( PersisterFactory.class ).createCollectionPersister( + cfg, + model, + accessStrategy, + this + ) ; collectionPersisters.put( model.getRole(), persister.getCollectionMetadata() ); Type indexType = persister.getIndexType(); if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/PersisterClassProvider.java b/hibernate-core/src/main/java/org/hibernate/persister/PersisterClassProvider.java deleted file mode 100644 index 029c4d0370..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/persister/PersisterClassProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * JBoss, Home of Professional Open Source - * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @authors tag. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU Lesser General Public License, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -package org.hibernate.persister; - -import org.hibernate.persister.collection.CollectionPersister; -import org.hibernate.persister.entity.EntityPersister; - -/** - * Provides persister classes based on the entity or collection role. - * The persister class is chosen according to the following rules in decreasing priority: - * - the persister class defined explicitly via annotation or XML - * - the persister class returned by the PersisterClassProvider implementation (if not null) - * - the default provider as chosen by Hibernate Core (best choice most of the time) - * - * @author Emmanuel Bernard - */ -public interface PersisterClassProvider { - /** - * Returns the entity persister class for a given entityName or null - * if the entity persister class should be the default. - */ - Class getEntityPersisterClass(String entityName); - - /** - * Returns the collection persister class for a given collection role or null - * if the collection persister class should be the default. - */ - Class getCollectionPersisterClass(String collectionPersister); -} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/PersisterFactory.java b/hibernate-core/src/main/java/org/hibernate/persister/PersisterFactory.java deleted file mode 100644 index e62c62f940..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/persister/PersisterFactory.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - * - */ -package org.hibernate.persister; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -import org.hibernate.HibernateException; -import org.hibernate.MappingException; -import org.hibernate.cache.access.EntityRegionAccessStrategy; -import org.hibernate.cache.access.CollectionRegionAccessStrategy; -import org.hibernate.cfg.Configuration; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.mapping.Collection; -import org.hibernate.mapping.PersistentClass; -import org.hibernate.persister.collection.BasicCollectionPersister; -import org.hibernate.persister.collection.CollectionPersister; -import org.hibernate.persister.collection.OneToManyPersister; -import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.persister.entity.JoinedSubclassEntityPersister; -import org.hibernate.persister.entity.SingleTableEntityPersister; -import org.hibernate.persister.entity.UnionSubclassEntityPersister; - -/** - * Factory for EntityPersister and CollectionPersister instances - * - * @author Gavin King - */ -public final class PersisterFactory { - - //TODO: make EntityPersister *not* depend on SessionFactoryImplementor - //interface, if possible - - // TODO : still need to make CollectionPersisters EntityMode-aware - - private PersisterFactory() {} - - private static final Class[] PERSISTER_CONSTRUCTOR_ARGS = new Class[] { - PersistentClass.class, EntityRegionAccessStrategy.class, SessionFactoryImplementor.class, Mapping.class - }; - - // TODO: is it really neceassry to provide Configuration to CollectionPersisters ? Should it not be enough with associated class ? - // or why does EntityPersister's not get access to configuration ? - // - // The only reason I could see that Configuration gets passed to collection persisters - // is so that they can look up the dom4j node name of the entity element in case - // no explicit node name was applied at the collection element level. Are you kidding me? - // Trivial to fix then. Just store and expose the node name on the entity persister - // (which the collection persister looks up anyway via other means...). - private static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] { - Collection.class, CollectionRegionAccessStrategy.class, Configuration.class, SessionFactoryImplementor.class - }; - - public static EntityPersister createClassPersister( - PersistentClass model, - EntityRegionAccessStrategy cacheAccessStrategy, - SessionFactoryImplementor factory, - Mapping cfg) throws HibernateException { - Class persisterClass = model.getEntityPersisterClass(); - if ( persisterClass == null || persisterClass == SingleTableEntityPersister.class ) { - return new SingleTableEntityPersister( model, cacheAccessStrategy, factory, cfg ); - } - else if ( persisterClass == JoinedSubclassEntityPersister.class ) { - return new JoinedSubclassEntityPersister( model, cacheAccessStrategy, factory, cfg ); - } - else if ( persisterClass == UnionSubclassEntityPersister.class ) { - return new UnionSubclassEntityPersister( model, cacheAccessStrategy, factory, cfg ); - } - else { - return create( persisterClass, model, cacheAccessStrategy, factory, cfg ); - } - } - - public static CollectionPersister createCollectionPersister( - Configuration cfg, - Collection model, - CollectionRegionAccessStrategy cacheAccessStrategy, - SessionFactoryImplementor factory) throws HibernateException { - Class persisterClass = model.getCollectionPersisterClass(); - if ( persisterClass == null ) { - return model.isOneToMany() - ? ( CollectionPersister ) new OneToManyPersister( model, cacheAccessStrategy, cfg, factory ) - : ( CollectionPersister ) new BasicCollectionPersister( model, cacheAccessStrategy, cfg, factory ); - } - else { - return create( persisterClass, cfg, model, cacheAccessStrategy, factory ); - } - - } - - private static EntityPersister create( - Class persisterClass, - PersistentClass model, - EntityRegionAccessStrategy cacheAccessStrategy, - SessionFactoryImplementor factory, - Mapping cfg) throws HibernateException { - Constructor pc; - try { - pc = persisterClass.getConstructor( PERSISTER_CONSTRUCTOR_ARGS ); - } - catch ( Exception e ) { - throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e ); - } - - try { - return (EntityPersister) pc.newInstance( new Object[] { model, cacheAccessStrategy, factory, cfg } ); - } - catch (InvocationTargetException ite) { - Throwable e = ite.getTargetException(); - if (e instanceof HibernateException) { - throw (HibernateException) e; - } - else { - throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e ); - } - } - catch (Exception e) { - throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e ); - } - } - - private static CollectionPersister create( - Class persisterClass, - Configuration cfg, - Collection model, - CollectionRegionAccessStrategy cacheAccessStrategy, - SessionFactoryImplementor factory) throws HibernateException { - Constructor pc; - try { - pc = persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS ); - } - catch (Exception e) { - throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e ); - } - - try { - return (CollectionPersister) pc.newInstance( new Object[] { model, cacheAccessStrategy, cfg, factory } ); - } - catch (InvocationTargetException ite) { - Throwable e = ite.getTargetException(); - if (e instanceof HibernateException) { - throw (HibernateException) e; - } - else { - throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e ); - } - } - catch (Exception e) { - throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e ); - } - } - - -} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java new file mode 100644 index 0000000000..f61b48fd6a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java @@ -0,0 +1,69 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.persister.internal; + +import org.hibernate.persister.spi.PersisterClassResolver; +import org.hibernate.service.classloading.spi.ClassLoaderService; +import org.hibernate.service.spi.ServiceException; +import org.hibernate.service.spi.ServiceInitiator; +import org.hibernate.service.spi.ServiceRegistry; + +import java.util.Map; + +/** + * @author Steve Ebersole + */ +public class PersisterClassResolverInitiator implements ServiceInitiator { + public static final PersisterClassResolverInitiator INSTANCE = new PersisterClassResolverInitiator(); + public static final String IMPL_NAME = "hibernate.persister.resolver"; + + @Override + public Class getServiceInitiated() { + return PersisterClassResolver.class; + } + + @Override + @SuppressWarnings( {"unchecked"}) + public PersisterClassResolver initiateService(Map configurationValues, ServiceRegistry registry) { + final Object customImpl = configurationValues.get( IMPL_NAME ); + if ( customImpl == null ) { + return new StandardPersisterClassResolver(); + } + + if ( PersisterClassResolver.class.isInstance( customImpl ) ) { + return (PersisterClassResolver) customImpl; + } + + final Class customImplClass = Class.class.isInstance( customImpl ) + ? (Class) customImpl + : registry.getService( ClassLoaderService.class ).classForName( customImpl.toString() ); + + try { + return customImplClass.newInstance(); + } + catch (Exception e) { + throw new ServiceException( "Could not initialize custom PersisterClassResolver impl [" + customImplClass.getName() + "]", e ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java new file mode 100644 index 0000000000..c56523a9b9 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java @@ -0,0 +1,183 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.persister.internal; + +import org.hibernate.HibernateException; +import org.hibernate.MappingException; +import org.hibernate.cache.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.access.EntityRegionAccessStrategy; +import org.hibernate.cfg.Configuration; +import org.hibernate.engine.Mapping; +import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.mapping.Collection; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.spi.PersisterClassResolver; +import org.hibernate.persister.spi.PersisterFactory; +import org.hibernate.service.spi.ServiceRegistry; +import org.hibernate.service.spi.ServiceRegistryAwareService; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +/** + * The standard Hibernate {@link PersisterFactory} implementation + * + * @author Gavin King + * @author Steve Ebersole + */ +public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegistryAwareService { + + /** + * The constructor signature for {@link EntityPersister} implementations + * + * @todo make EntityPersister *not* depend on {@link SessionFactoryImplementor} if possible. + */ + public static final Class[] ENTITY_PERSISTER_CONSTRUCTOR_ARGS = new Class[] { + PersistentClass.class, + EntityRegionAccessStrategy.class, + SessionFactoryImplementor.class, + Mapping.class + }; + + /** + * The constructor signature for {@link CollectionPersister} implementations + * + * @todo still need to make collection persisters EntityMode-aware + * @todo make EntityPersister *not* depend on {@link SessionFactoryImplementor} if possible. + */ + private static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] { + Collection.class, + CollectionRegionAccessStrategy.class, + Configuration.class, + SessionFactoryImplementor.class + }; + + private ServiceRegistry serviceRegistry; + + @Override + public void injectServices(ServiceRegistry serviceRegistry) { + this.serviceRegistry = serviceRegistry; + } + + @Override + @SuppressWarnings( {"unchecked"}) + public EntityPersister createEntityPersister( + PersistentClass metadata, + EntityRegionAccessStrategy cacheAccessStrategy, + SessionFactoryImplementor factory, + Mapping cfg) { + Class persisterClass = metadata.getEntityPersisterClass(); + if ( persisterClass == null ) { + persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getEntityPersisterClass( metadata ); + } + return create( persisterClass, metadata, cacheAccessStrategy, factory, cfg ); + } + + private static EntityPersister create( + Class persisterClass, + PersistentClass metadata, + EntityRegionAccessStrategy cacheAccessStrategy, + SessionFactoryImplementor factory, + Mapping cfg) throws HibernateException { + try { + Constructor constructor = persisterClass.getConstructor( ENTITY_PERSISTER_CONSTRUCTOR_ARGS ); + try { + return constructor.newInstance( metadata, cacheAccessStrategy, factory, cfg ); + } + catch (MappingException e) { + throw e; + } + catch (InvocationTargetException e) { + Throwable target = e.getTargetException(); + if ( target instanceof HibernateException ) { + throw (HibernateException) target; + } + else { + throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), target ); + } + } + catch (Exception e) { + throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e ); + } + } + catch (MappingException e) { + throw e; + } + catch (Exception e) { + throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e ); + } + } + + @Override + @SuppressWarnings( {"unchecked"}) + public CollectionPersister createCollectionPersister( + Configuration cfg, + Collection metadata, + CollectionRegionAccessStrategy cacheAccessStrategy, + SessionFactoryImplementor factory) throws HibernateException { + Class persisterClass = metadata.getCollectionPersisterClass(); + if ( persisterClass == null ) { + persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getCollectionPersisterClass( metadata ); + } + + return create( persisterClass, cfg, metadata, cacheAccessStrategy, factory ); + } + + private static CollectionPersister create( + Class persisterClass, + Configuration cfg, + Collection metadata, + CollectionRegionAccessStrategy cacheAccessStrategy, + SessionFactoryImplementor factory) throws HibernateException { + try { + Constructor constructor = persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS ); + try { + return constructor.newInstance( metadata, cacheAccessStrategy, cfg, factory ); + } + catch (MappingException e) { + throw e; + } + catch (InvocationTargetException e) { + Throwable target = e.getTargetException(); + if ( target instanceof HibernateException ) { + throw (HibernateException) target; + } + else { + throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), target ); + } + } + catch (Exception e) { + throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e ); + } + } + catch (MappingException e) { + throw e; + } + catch (Exception e) { + throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryInitiator.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryInitiator.java new file mode 100644 index 0000000000..73df183a37 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryInitiator.java @@ -0,0 +1,69 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.persister.internal; + +import org.hibernate.persister.spi.PersisterFactory; +import org.hibernate.service.classloading.spi.ClassLoaderService; +import org.hibernate.service.spi.ServiceException; +import org.hibernate.service.spi.ServiceInitiator; +import org.hibernate.service.spi.ServiceRegistry; + +import java.util.Map; + +/** + * @author Steve Ebersole + */ +public class PersisterFactoryInitiator implements ServiceInitiator { + public static final PersisterFactoryInitiator INSTANCE = new PersisterFactoryInitiator(); + + public static final String IMPL_NAME = "hibernate.persister.factory"; + + @Override + public Class getServiceInitiated() { + return PersisterFactory.class; + } + + @Override + @SuppressWarnings( {"unchecked"}) + public PersisterFactory initiateService(Map configurationValues, ServiceRegistry registry) { + final Object customImpl = configurationValues.get( IMPL_NAME ); + if ( customImpl == null ) { + return new PersisterFactoryImpl(); + } + + if ( PersisterFactory.class.isInstance( customImpl ) ) { + return (PersisterFactory) customImpl; + } + + final Class customImplClass = Class.class.isInstance( customImpl ) + ? ( Class ) customImpl + : registry.getService( ClassLoaderService.class ).classForName( customImpl.toString() ); + try { + return customImplClass.newInstance(); + } + catch (Exception e) { + throw new ServiceException( "Could not initialize custom PersisterFactory impl [" + customImplClass.getName() + "]", e ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java new file mode 100644 index 0000000000..6261b85578 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java @@ -0,0 +1,88 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.persister.internal; + +import org.hibernate.mapping.Collection; +import org.hibernate.mapping.JoinedSubclass; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.RootClass; +import org.hibernate.mapping.UnionSubclass; +import org.hibernate.persister.collection.BasicCollectionPersister; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.collection.OneToManyPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.JoinedSubclassEntityPersister; +import org.hibernate.persister.entity.SingleTableEntityPersister; +import org.hibernate.persister.entity.UnionSubclassEntityPersister; +import org.hibernate.persister.spi.PersisterClassResolver; +import org.hibernate.persister.spi.UnknownPersisterException; + +/** + * @author Steve Ebersole + */ +public class StandardPersisterClassResolver implements PersisterClassResolver { + @Override + public Class 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! + if ( RootClass.class.isInstance( metadata ) ) { + return singleTableEntityPersister(); + } + else if ( JoinedSubclass.class.isInstance( metadata ) ) { + return joinedSubclassEntityPersister(); + } + else if ( UnionSubclass.class.isInstance( metadata ) ) { + return unionSubclassEntityPersister(); + } + else { + throw new UnknownPersisterException( + "Could not determine persister implementation for entity [" + metadata.getEntityName() + "]" + ); + } + } + + public Class singleTableEntityPersister() { + return SingleTableEntityPersister.class; + } + + public Class joinedSubclassEntityPersister() { + return JoinedSubclassEntityPersister.class; + } + + public Class unionSubclassEntityPersister() { + return UnionSubclassEntityPersister.class; + } + + @Override + public Class getCollectionPersisterClass(Collection metadata) { + return metadata.isOneToMany() ? oneToManyPersister() : basicCollectionPersister(); + } + + private Class oneToManyPersister() { + return OneToManyPersister.class; + } + + private Class basicCollectionPersister() { + return BasicCollectionPersister.class; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterClassResolver.java b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterClassResolver.java new file mode 100644 index 0000000000..1137d12333 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterClassResolver.java @@ -0,0 +1,54 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.persister.spi; + +import org.hibernate.mapping.Collection; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.service.spi.Service; + +/** + * Provides persister classes based on the entity or collection role. + * The persister class is chosen according to the following rules in decreasing priority: + * - the persister class defined explicitly via annotation or XML + * - the persister class returned by the PersisterClassResolver implementation (if not null) + * - the default provider as chosen by Hibernate Core (best choice most of the time) + * + * @author Emmanuel Bernard + * @author Steve Ebersole + */ +public interface PersisterClassResolver extends Service { + /** + * Returns the entity persister class for a given entityName or null + * if the entity persister class should be the default. + */ + Class getEntityPersisterClass(PersistentClass metadata); + + /** + * Returns the collection persister class for a given collection role or null + * if the collection persister class should be the default. + */ + Class getCollectionPersisterClass(Collection metadata); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java new file mode 100644 index 0000000000..1108fa1752 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java @@ -0,0 +1,89 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.persister.spi; + +import org.hibernate.HibernateException; +import org.hibernate.cache.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.access.EntityRegionAccessStrategy; +import org.hibernate.cfg.Configuration; +import org.hibernate.engine.Mapping; +import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.mapping.Collection; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.service.spi.Service; + +/** + * Contract for creating persister instances (both {@link EntityPersister} and {@link } varieties). + * + * @author Steve Ebersole + */ +public interface PersisterFactory extends Service { + + // TODO: is it really neceassry to provide Configuration to CollectionPersisters ? + // Should it not be enough with associated class ? or why does EntityPersister's not get access to configuration ? + // + // The only reason I could see that Configuration gets passed to collection persisters + // is so that they can look up the dom4j node name of the entity element in case + // no explicit node name was applied at the collection element level. Are you kidding me? + // Trivial to fix then. Just store and expose the node name on the entity persister + // (which the collection persister looks up anyway via other means...). + + /** + * 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( + PersistentClass model, + EntityRegionAccessStrategy cacheAccessStrategy, + SessionFactoryImplementor factory, + Mapping cfg) 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, + Collection model, + CollectionRegionAccessStrategy cacheAccessStrategy, + SessionFactoryImplementor factory) throws HibernateException; +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/spi/UnknownPersisterException.java b/hibernate-core/src/main/java/org/hibernate/persister/spi/UnknownPersisterException.java new file mode 100644 index 0000000000..f5b67d6e84 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/spi/UnknownPersisterException.java @@ -0,0 +1,41 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.persister.spi; + +import org.hibernate.HibernateException; + +/** + * Indicates that the persister to use is not known and couyld not be determined. + * + * @author Steve Ebersole + */ +public class UnknownPersisterException extends HibernateException { + public UnknownPersisterException(String s) { + super( s ); + } + + public UnknownPersisterException(String string, Throwable root) { + super( string, root ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java b/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java index a6b8a545e7..f3d2eba700 100644 --- a/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java +++ b/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java @@ -26,6 +26,8 @@ package org.hibernate.service.spi; import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator; import org.hibernate.engine.jdbc.internal.JdbcServicesInitiator; import org.hibernate.engine.transaction.internal.TransactionFactoryInitiator; +import org.hibernate.persister.internal.PersisterClassResolverInitiator; +import org.hibernate.persister.internal.PersisterFactoryInitiator; import org.hibernate.service.classloading.internal.ClassLoaderServiceInitiator; import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator; import org.hibernate.service.jdbc.dialect.internal.DialectFactoryInitiator; @@ -50,6 +52,9 @@ public class StandardServiceInitiators { serviceInitiators.add( JndiServiceInitiator.INSTANCE ); serviceInitiators.add( JmxServiceInitiator.INSTANCE ); + serviceInitiators.add( PersisterClassResolverInitiator.INSTANCE ); + serviceInitiators.add( PersisterFactoryInitiator.INSTANCE ); + serviceInitiators.add( ConnectionProviderInitiator.INSTANCE ); serviceInitiators.add( DialectResolverInitiator.INSTANCE ); serviceInitiators.add( DialectFactoryInitiator.INSTANCE ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java index 2cdcb817c2..9c09506736 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java +++ b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java @@ -41,9 +41,10 @@ import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.ValueInclusion; import org.hibernate.id.IdentifierGenerator; import org.hibernate.mapping.Collection; +import org.hibernate.mapping.PersistentClass; import org.hibernate.metadata.ClassMetadata; import org.hibernate.metadata.CollectionMetadata; -import org.hibernate.persister.PersisterClassProvider; +import org.hibernate.persister.spi.PersisterClassResolver; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.tuple.entity.EntityMetamodel; @@ -54,12 +55,14 @@ import org.hibernate.type.VersionType; /** * @author Emmanuel Bernard */ -public class GoofyPersisterClassProvider implements PersisterClassProvider { - public Class getEntityPersisterClass(String entityName) { +public class GoofyPersisterClassProvider implements PersisterClassResolver { + @Override + public Class getEntityPersisterClass(PersistentClass metadata) { return NoopEntityPersister.class; } - public Class getCollectionPersisterClass(String collectionPersister) { + @Override + public Class getCollectionPersisterClass(Collection metadata) { return NoopCollectionPersister.class; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/PersisterClassProviderTest.java b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/PersisterClassProviderTest.java index d94a8952ba..46211c597c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/PersisterClassProviderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/PersisterClassProviderTest.java @@ -23,6 +23,7 @@ package org.hibernate.test.cfg.persister; import org.hibernate.MappingException; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; +import org.hibernate.persister.spi.PersisterClassResolver; import org.hibernate.service.spi.ServiceRegistry; import org.hibernate.testing.ServiceRegistryBuilder; import org.hibernate.testing.junit.UnitTestCase; @@ -44,10 +45,9 @@ public class PersisterClassProviderTest extends UnitTestCase { SessionFactory sessionFactory = cfg.buildSessionFactory( serviceRegistry ); sessionFactory.close(); - + serviceRegistry.registerService( PersisterClassResolver.class, new GoofyPersisterClassProvider() ); cfg = new Configuration(); cfg.addAnnotatedClass( Gate.class ); - cfg.setPersisterClassProvider( new GoofyPersisterClassProvider() ); try { sessionFactory = cfg.buildSessionFactory( serviceRegistry ); sessionFactory.close(); @@ -63,7 +63,6 @@ public class PersisterClassProviderTest extends UnitTestCase { cfg = new Configuration(); cfg.addAnnotatedClass( Portal.class ); cfg.addAnnotatedClass( Window.class ); - cfg.setPersisterClassProvider( new GoofyPersisterClassProvider() ); try { sessionFactory = cfg.buildSessionFactory( serviceRegistry ); sessionFactory.close(); diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java index 92c64df0ad..e53a801690 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java @@ -247,7 +247,7 @@ public class AvailableSettings { public static final String NAMING_STRATEGY = "hibernate.ejb.naming_strategy"; /** - * PersisterClassProvider class name, the class has to gave a no-arg constructor + * PersisterClassResolver class name, the class has to gave a no-arg constructor */ public static final String PERSISTER_CLASS_PROVIDER = "hibernate.ejb.persister_class_provider"; diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java index 07eaa01b90..56a882f1d7 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java @@ -91,7 +91,6 @@ import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory; import org.hibernate.event.EventListeners; import org.hibernate.mapping.AuxiliaryDatabaseObject; import org.hibernate.mapping.PersistentClass; -import org.hibernate.persister.PersisterClassProvider; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.secure.JACCConfiguration; import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator; @@ -1049,18 +1048,6 @@ public class Ejb3Configuration implements Serializable, Referenceable { cfg.setNamingStrategy( namingStrategy ); } - final PersisterClassProvider persisterClassProvider = instantiateCustomClassFromConfiguration( - preparedProperties, - null, - cfg.getPersisterClassProvider(), - AvailableSettings.PERSISTER_CLASS_PROVIDER, - "persister class provider", - PersisterClassProvider.class - ); - if ( persisterClassProvider != null ) { - cfg.setPersisterClassProvider( persisterClassProvider ); - } - if ( jaccKeys.size() > 0 ) { addSecurity( jaccKeys, preparedProperties, workingVars ); } @@ -1581,11 +1568,6 @@ public class Ejb3Configuration implements Serializable, Referenceable { return this; } - public Ejb3Configuration setPersisterClassProvider(PersisterClassProvider persisterClassProvider) { - cfg.setPersisterClassProvider( persisterClassProvider ); - return this; - } - public void setListeners(String type, String[] listenerClasses) { cfg.setListeners( type, listenerClasses ); } diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java index a3935788a1..16d07eaba7 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java @@ -40,8 +40,11 @@ import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.ValueInclusion; import org.hibernate.id.IdentifierGenerator; +import org.hibernate.mapping.Collection; +import org.hibernate.mapping.PersistentClass; import org.hibernate.metadata.ClassMetadata; -import org.hibernate.persister.PersisterClassProvider; +import org.hibernate.persister.internal.PersisterClassResolverInitiator; +import org.hibernate.persister.spi.PersisterClassResolver; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.tuple.entity.EntityMetamodel; @@ -54,7 +57,7 @@ import org.hibernate.type.VersionType; public class PersisterClassProviderTest extends junit.framework.TestCase { public void testPersisterClassProvider() { Ejb3Configuration conf = new Ejb3Configuration(); - conf.setPersisterClassProvider( new GoofyPersisterClassProvider() ); + conf.getProperties().put( PersisterClassResolverInitiator.IMPL_NAME, GoofyPersisterClassProvider.class ); conf.addAnnotatedClass( Bell.class ); try { final EntityManagerFactory entityManagerFactory = conf.buildEntityManagerFactory(); @@ -68,13 +71,14 @@ public class PersisterClassProviderTest extends junit.framework.TestCase { } } - public static class GoofyPersisterClassProvider implements PersisterClassProvider { - - public Class getEntityPersisterClass(String entityName) { + public static class GoofyPersisterClassProvider implements PersisterClassResolver { + @Override + public Class getEntityPersisterClass(PersistentClass metadata) { return GoofyProvider.class; } - public Class getCollectionPersisterClass(String collectionPersister) { + @Override + public Class getCollectionPersisterClass(Collection metadata) { return null; } }