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 e92dc075b7..5f770cb4f0 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java @@ -79,6 +79,7 @@ import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.annotations.common.reflection.java.JavaReflectionManager; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; @@ -86,6 +87,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.function.SQLFunction; import org.hibernate.engine.ResultSetMappingDefinition; +import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.NamedQueryDefinition; @@ -133,15 +135,17 @@ import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.mapping.TypeDef; import org.hibernate.mapping.UniqueKey; +import org.hibernate.metamodel.spi.TypeContributions; +import org.hibernate.metamodel.spi.TypeContributor; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.secure.spi.GrantedPermission; import org.hibernate.secure.spi.JaccPermissionDeclarations; import org.hibernate.service.ServiceRegistry; -import org.hibernate.tool.hbm2ddl.UniqueConstraintSchemaUpdateStrategy; import org.hibernate.tool.hbm2ddl.DatabaseMetadata; import org.hibernate.tool.hbm2ddl.IndexMetadata; import org.hibernate.tool.hbm2ddl.SchemaUpdateScript; import org.hibernate.tool.hbm2ddl.TableMetadata; +import org.hibernate.tool.hbm2ddl.UniqueConstraintSchemaUpdateStrategy; import org.hibernate.tuple.entity.EntityTuplizerFactory; import org.hibernate.type.BasicType; import org.hibernate.type.SerializationException; @@ -223,7 +227,9 @@ public class Configuration implements Serializable { protected Map extendsQueue; protected Map sqlFunctions; + private TypeResolver typeResolver = new TypeResolver(); + private List typeContributorRegistrations = new ArrayList(); private EntityTuplizerFactory entityTuplizerFactory; // private ComponentTuplizerFactory componentTuplizerFactory; todo : HHH-3517 and HHH-1907 @@ -1782,7 +1788,8 @@ public class Configuration implements Serializable { */ public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throws HibernateException { LOG.debugf( "Preparing to build session factory with filters : %s", filterDefinitions ); - + + buildTypeRegistrations( serviceRegistry ); secondPassCompile(); if ( !metadataSourceQueue.isEmpty() ) { LOG.incompleteMappingMetadataCacheProcessing(); @@ -1804,6 +1811,39 @@ public class Configuration implements Serializable { sessionFactoryObserver ); } + + private void buildTypeRegistrations(ServiceRegistry serviceRegistry) { + final TypeContributions typeContributions = new TypeContributions() { + @Override + public void contributeType(BasicType type) { + typeResolver.registerTypeOverride( type ); + } + + @Override + public void contributeType(UserType type, String[] keys) { + typeResolver.registerTypeOverride( type, keys ); + } + + @Override + public void contributeType(CompositeUserType type, String[] keys) { + typeResolver.registerTypeOverride( type, keys ); + } + }; + + // add Dialect contributed types + final Dialect dialect = serviceRegistry.getService( JdbcServices.class ).getDialect(); + dialect.contributeTypes( typeContributions, serviceRegistry ); + + // add TypeContributor contributed types. + ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class ); + for ( TypeContributor contributor : classLoaderService.loadJavaServices( TypeContributor.class ) ) { + contributor.contribute( typeContributions, serviceRegistry ); + } + // from app registrations + for ( TypeContributor contributor : typeContributorRegistrations ) { + contributor.contribute( typeContributions, serviceRegistry ); + } + } /** * Create a {@link SessionFactory} using the properties and mappings in this configuration. The @@ -2510,6 +2550,10 @@ public class Configuration implements Serializable { getTypeResolver().registerTypeOverride( type, keys ); } + public void registerTypeContributor(TypeContributor typeContributor) { + typeContributorRegistrations.add( typeContributor ); + } + public SessionFactoryObserver getSessionFactoryObserver() { return sessionFactoryObserver; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/TypeContributor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/TypeContributor.java index 004caef5e6..4a04173faa 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/TypeContributor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/TypeContributor.java @@ -29,6 +29,9 @@ import org.hibernate.service.ServiceRegistry; * Contract for contributing types. * * @author Steve Ebersole + * + * NOTE: Cherry-pick of HHH-7998 from metamodel. For merging simplicity, just + * keep it in the o.h.metamodel.spi package. */ public interface TypeContributor { /** diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java index 433aa11465..eb3fe79eba 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java @@ -88,6 +88,7 @@ import org.hibernate.jpa.boot.spi.NamedInputStream; import org.hibernate.jpa.boot.spi.PackageDescriptor; import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor; import org.hibernate.jpa.boot.spi.StrategyRegistrationProviderList; +import org.hibernate.jpa.boot.spi.TypeContributorList; import org.hibernate.jpa.event.spi.JpaIntegrator; import org.hibernate.jpa.internal.EntityManagerFactoryImpl; import org.hibernate.jpa.internal.EntityManagerMessageLogger; @@ -97,6 +98,7 @@ import org.hibernate.jpa.internal.util.PersistenceUnitTransactionTypeHelper; import org.hibernate.jpa.spi.IdentifierGeneratorStrategyProvider; import org.hibernate.metamodel.source.annotations.JPADotNames; import org.hibernate.metamodel.source.annotations.JandexHelper; +import org.hibernate.metamodel.spi.TypeContributor; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.secure.spi.GrantedPermission; import org.hibernate.secure.spi.JaccService; @@ -135,6 +137,11 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil * Names a {@link StrategyRegistrationProviderList} */ public static final String STRATEGY_REGISTRATION_PROVIDERS = "hibernate.strategy_registration_provider"; + + /** + * Names a {@link TypeContributorList} + */ + public static final String TYPE_CONTRIBUTORS = "hibernate.type_contributors"; /** * Names a Jandex {@link Index} instance to use. @@ -1166,6 +1173,16 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil for ( String packageName : metadataSources.packageNames ) { cfg.addPackage( packageName ); } + + final TypeContributorList typeContributorList + = (TypeContributorList) configurationValues.get( TYPE_CONTRIBUTORS ); + if ( typeContributorList != null ) { + configurationValues.remove( TYPE_CONTRIBUTORS ); + for ( TypeContributor typeContributor : typeContributorList.getTypeContributors() ) { + cfg.registerTypeContributor( typeContributor ); + } + } + return cfg; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/TypeContributorImpl.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/TypeContributorImpl.java new file mode 100644 index 0000000000..0a49200a26 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/TypeContributorImpl.java @@ -0,0 +1,38 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * JBoss, Home of Professional Open Source + * Copyright 2013 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.envers.internal.entities; + +import org.hibernate.metamodel.spi.TypeContributions; +import org.hibernate.metamodel.spi.TypeContributor; +import org.hibernate.service.ServiceRegistry; + +/** + * @author Brett Meyer + */ +public class TypeContributorImpl implements TypeContributor { + + @Override + public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { + typeContributions.contributeType( new RevisionTypeType(), + new String[] { RevisionTypeType.class.getName() } ); + } + +} diff --git a/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.metamodel.spi.TypeContributor b/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.metamodel.spi.TypeContributor new file mode 100644 index 0000000000..5eeaedd30c --- /dev/null +++ b/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.metamodel.spi.TypeContributor @@ -0,0 +1 @@ +org.hibernate.envers.internal.entities.TypeContributorImpl \ No newline at end of file diff --git a/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml index 07c01bfc9f..9fc677c57e 100644 --- a/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -6,5 +6,8 @@ + + + diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java index 23cc77d8b7..c99715b8e5 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java @@ -37,7 +37,8 @@ import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; import org.hibernate.jpa.boot.spi.IntegratorProvider; import org.hibernate.jpa.boot.spi.StrategyRegistrationProviderList; - +import org.hibernate.jpa.boot.spi.TypeContributorList; +import org.hibernate.metamodel.spi.TypeContributor; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleReference; @@ -135,6 +136,15 @@ public class OsgiPersistenceProvider extends HibernatePersistenceProvider { } }; settings.put( EntityManagerFactoryBuilderImpl.STRATEGY_REGISTRATION_PROVIDERS, strategyRegistrationProviderList ); + + final List typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context ); + TypeContributorList typeContributorList = new TypeContributorList() { + @Override + public List getTypeContributors() { + return typeContributors; + } + }; + settings.put( EntityManagerFactoryBuilderImpl.TYPE_CONTRIBUTORS, typeContributorList ); return settings; } diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java index af6c57be4d..71b45387c9 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java @@ -22,11 +22,6 @@ package org.hibernate.osgi; import java.util.List; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceFactory; -import org.osgi.framework.ServiceRegistration; - import org.hibernate.SessionFactory; import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; @@ -34,7 +29,12 @@ import org.hibernate.boot.registry.selector.StrategyRegistrationProvider; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; import org.hibernate.integrator.spi.Integrator; +import org.hibernate.metamodel.spi.TypeContributor; import org.hibernate.service.ServiceRegistry; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceFactory; +import org.osgi.framework.ServiceRegistration; /** * Hibernate 4.2 and 4.3 still heavily rely on TCCL for ClassLoading. Although @@ -96,6 +96,11 @@ public class OsgiSessionFactoryService implements ServiceFactory { for ( StrategyRegistrationProvider strategyRegistrationProvider : strategyRegistrationProviders ) { builder.withStrategySelectors( strategyRegistrationProvider ); } + + final List typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context ); + for (TypeContributor typeContributor : typeContributors) { + configuration.registerTypeContributor( typeContributor ); + } final ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder( builder.build() ) .applySettings( configuration.getProperties() ).build();