HHH-7995 Added support for TypeContributors in OSGi. Integrated with

envers
This commit is contained in:
Brett Meyer 2013-04-30 12:50:02 -04:00
parent aecd5a444b
commit 8e3fd81046
8 changed files with 120 additions and 13 deletions

View File

@ -81,6 +81,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;
@ -128,10 +129,13 @@ 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.internal.JACCConfiguration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.internal.StandardServiceRegistryImpl;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
import org.hibernate.tool.hbm2ddl.IndexMetadata;
@ -219,7 +223,9 @@ public class Configuration implements Serializable {
protected Map<ExtendsQueueEntry, ?> extendsQueue;
protected Map<String, SQLFunction> sqlFunctions;
private TypeResolver typeResolver = new TypeResolver();
private List<TypeContributor> typeContributorRegistrations = new ArrayList<TypeContributor>();
private EntityTuplizerFactory entityTuplizerFactory;
// private ComponentTuplizerFactory componentTuplizerFactory; todo : HHH-3517 and HHH-1907
@ -1743,7 +1749,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();
@ -1765,6 +1772,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
@ -2452,6 +2492,10 @@ public class Configuration implements Serializable {
getTypeResolver().registerTypeOverride( type, keys );
}
public void registerTypeContributor(TypeContributor typeContributor) {
typeContributorRegistrations.add( typeContributor );
}
public SessionFactoryObserver getSessionFactoryObserver() {
return sessionFactoryObserver;
}

View File

@ -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 {
/**

View File

@ -45,6 +45,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import javax.naming.BinaryRefAddr;
import javax.naming.NamingException;
import javax.naming.Reference;
@ -60,10 +61,6 @@ import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import org.dom4j.Element;
import org.jboss.logging.Logger;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MappingException;
@ -103,6 +100,7 @@ import org.hibernate.internal.util.xml.OriginImpl;
import org.hibernate.internal.util.xml.XmlDocument;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.spi.TypeContributor;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.internal.JACCConfiguration;
import org.hibernate.service.BootstrapServiceRegistryBuilder;
@ -110,6 +108,9 @@ import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.internal.StandardServiceRegistryImpl;
import org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl;
import org.jboss.logging.Logger;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
/**
* Allow a fine tuned configuration of an EJB 3.0 EntityManagerFactory
@ -1655,6 +1656,11 @@ public class Ejb3Configuration implements Serializable, Referenceable {
cfg.addResource( path, classLoader );
return this;
}
public Ejb3Configuration addTypeContributor(TypeContributor typeContributor) {
cfg.registerTypeContributor( typeContributor );
return this;
}
private enum XML_SEARCH {
HBM,

View File

@ -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.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() } );
}
}

View File

@ -0,0 +1 @@
org.hibernate.envers.entities.TypeContributorImpl

View File

@ -6,5 +6,8 @@
<bean id="integrator" class="org.hibernate.envers.event.EnversIntegrator"/>
<service ref="integrator" interface="org.hibernate.integrator.spi.Integrator"/>
<bean id="typeContributor" class="org.hibernate.envers.entities.TypeContributorImpl"/>
<service ref="typeContributor" interface="org.hibernate.metamodel.spi.TypeContributor"/>
</blueprint>

View File

@ -35,6 +35,7 @@ import org.hibernate.cfg.AvailableSettings;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.ejb.HibernatePersistence;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.metamodel.spi.TypeContributor;
import org.hibernate.osgi.util.OsgiServiceUtil;
import org.hibernate.service.BootstrapServiceRegistryBuilder;
import org.osgi.framework.Bundle;
@ -68,7 +69,7 @@ public class OsgiPersistenceProvider extends HibernatePersistence {
@Override
public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
generateProperties( properties );
properties = generateProperties( properties );
// TODO: This needs tested.
properties.put( org.hibernate.ejb.AvailableSettings.SCANNER, new OsgiScanner( requestingBundle ) );
@ -80,12 +81,12 @@ public class OsgiPersistenceProvider extends HibernatePersistence {
Ejb3Configuration cfg = new Ejb3Configuration();
Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties );
return configured != null ? configured.buildEntityManagerFactory( getBuilder( properties ) ) : null;
return configured != null ? configured.buildEntityManagerFactory( getBuilder( cfg, properties ) ) : null;
}
@Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
generateProperties( properties );
properties = generateProperties( properties );
// OSGi ClassLoaders must implement BundleReference
properties.put( org.hibernate.ejb.AvailableSettings.SCANNER,
@ -95,10 +96,10 @@ public class OsgiPersistenceProvider extends HibernatePersistence {
Ejb3Configuration cfg = new Ejb3Configuration();
Ejb3Configuration configured = cfg.configure( info, properties );
return configured != null ? configured.buildEntityManagerFactory( getBuilder( properties ) ) : null;
return configured != null ? configured.buildEntityManagerFactory( getBuilder( cfg, properties ) ) : null;
}
private BootstrapServiceRegistryBuilder getBuilder(Map properties) {
private BootstrapServiceRegistryBuilder getBuilder(Ejb3Configuration cfg, Map properties) {
BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
final Collection<ClassLoader> classLoaders = (Collection<ClassLoader>) properties
@ -114,17 +115,22 @@ public class OsgiPersistenceProvider extends HibernatePersistence {
for ( Integrator integrator : integrators ) {
builder.with( integrator );
}
// TODO: other types of services?
List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
for (TypeContributor typeContributor : typeContributors) {
cfg.addTypeContributor( typeContributor );
}
return builder;
}
private void generateProperties(Map properties) {
private Map generateProperties(Map properties) {
if ( properties == null ) {
properties = new HashMap();
}
properties.put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform );
return properties;
}
}

View File

@ -26,6 +26,7 @@ import org.hibernate.SessionFactory;
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.osgi.util.OsgiServiceUtil;
import org.hibernate.service.BootstrapServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;
@ -84,6 +85,11 @@ public class OsgiSessionFactoryService implements ServiceFactory {
builder.with( integrator );
}
List<TypeContributor> typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context );
for (TypeContributor typeContributor : typeContributors) {
configuration.registerTypeContributor( typeContributor );
}
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder( builder.build() )
.applySettings(configuration.getProperties()).buildServiceRegistry();
return configuration.buildSessionFactory(serviceRegistry);