HHH-7620 - allow ValidatorFactory to be passed into EntityManagerFactoryBuilder

This commit is contained in:
Steve Ebersole 2012-09-20 03:47:30 -05:00
parent 500e0222b5
commit 595f068977
11 changed files with 51 additions and 21 deletions

View File

@ -82,7 +82,7 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
continue; continue;
} }
return Bootstrap.getEntityManagerFactoryBuilder( persistenceUnit, integration ).buildEntityManagerFactory(); return Bootstrap.getEntityManagerFactoryBuilder( persistenceUnit, integration ).build();
} }
return null; return null;
@ -100,7 +100,7 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
*/ */
@Override @Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integration) { public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integration) {
return Bootstrap.getEntityManagerFactoryBuilder( info, integration ).buildEntityManagerFactory(); return Bootstrap.getEntityManagerFactoryBuilder( info, integration ).build();
} }
private final ProviderUtil providerUtil = new ProviderUtil() { private final ProviderUtil providerUtil = new ProviderUtil() {

View File

@ -133,7 +133,7 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
private final PersistenceUnitDescriptor persistenceUnit; private final PersistenceUnitDescriptor persistenceUnit;
private final SettingsImpl settings = new SettingsImpl(); private final SettingsImpl settings = new SettingsImpl();
private final StandardServiceRegistryBuilder serviceRegistryBuilder; private final StandardServiceRegistryBuilder serviceRegistryBuilder;
private final Map<?,?> configurationValues; private final Map configurationValues;
private final List<JaccDefinition> jaccDefinitions = new ArrayList<JaccDefinition>(); private final List<JaccDefinition> jaccDefinitions = new ArrayList<JaccDefinition>();
private final List<CacheRegionDefinition> cacheRegionDefinitions = new ArrayList<CacheRegionDefinition>(); private final List<CacheRegionDefinition> cacheRegionDefinitions = new ArrayList<CacheRegionDefinition>();
@ -148,6 +148,8 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
private static EntityNotFoundDelegate jpaEntityNotFoundDelegate = new JpaEntityNotFoundDelegate(); private static EntityNotFoundDelegate jpaEntityNotFoundDelegate = new JpaEntityNotFoundDelegate();
private Object validatorFactory;
private static class JpaEntityNotFoundDelegate implements EntityNotFoundDelegate, Serializable { private static class JpaEntityNotFoundDelegate implements EntityNotFoundDelegate, Serializable {
public void handleEntityNotFound(String entityName, Serializable id) { public void handleEntityNotFound(String entityName, Serializable id) {
throw new EntityNotFoundException( "Unable to find " + entityName + " with id " + id ); throw new EntityNotFoundException( "Unable to find " + entityName + " with id " + id );
@ -198,7 +200,8 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// temporary! // temporary!
public Map<?, ?> getConfigurationValues() { @SuppressWarnings("unchecked")
public Map getConfigurationValues() {
return Collections.unmodifiableMap( configurationValues ); return Collections.unmodifiableMap( configurationValues );
} }
@ -488,6 +491,8 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
applyJdbcConnectionProperties(); applyJdbcConnectionProperties();
applyTransactionProperties(); applyTransactionProperties();
// this check is needed for tests. Second form happens later (mainly against the explicitly passed validator)
// when building EMF...
final Object validationFactory = configurationValues.get( AvailableSettings.VALIDATION_FACTORY ); final Object validationFactory = configurationValues.get( AvailableSettings.VALIDATION_FACTORY );
if ( validationFactory != null ) { if ( validationFactory != null ) {
BeanValidationIntegrator.validateFactory( validationFactory ); BeanValidationIntegrator.validateFactory( validationFactory );
@ -499,7 +504,8 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION ); LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION );
} }
for ( Map.Entry entry : configurationValues.entrySet() ) { for ( Object oEntry : configurationValues.entrySet() ) {
Map.Entry entry = (Map.Entry) oEntry;
if ( entry.getKey() instanceof String ) { if ( entry.getKey() instanceof String ) {
final String keyString = (String) entry.getKey(); final String keyString = (String) entry.getKey();
@ -912,6 +918,12 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
} }
} }
@Override
public EntityManagerFactoryBuilder withValidatorFactory(Object validatorFactory) {
this.validatorFactory = validatorFactory;
return this;
}
@Override @Override
public void cancel() { public void cancel() {
// todo : close the bootstrap registry (not critical, but nice to do) // todo : close the bootstrap registry (not critical, but nice to do)
@ -919,11 +931,21 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public EntityManagerFactory buildEntityManagerFactory() { public EntityManagerFactory build() {
// IMPL NOTE : TCCL handling here is temporary. // IMPL NOTE : TCCL handling here is temporary.
// It is needed because this code still uses Hibernate Configuration and Hibernate commons-annotations // It is needed because this code still uses Hibernate Configuration and Hibernate commons-annotations
// in turn which relies on TCCL being set. // in turn which relies on TCCL being set.
if ( validatorFactory != null ) {
// NOTE : need to add it to both
configurationValues.put( AvailableSettings.VALIDATION_FACTORY, validatorFactory );
}
final Object validationFactory = configurationValues.get( AvailableSettings.VALIDATION_FACTORY );
if ( validationFactory != null ) {
BeanValidationIntegrator.validateFactory( validationFactory );
}
final ServiceRegistry serviceRegistry = buildServiceRegistry(); final ServiceRegistry serviceRegistry = buildServiceRegistry();
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class ); final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );

View File

@ -25,15 +25,13 @@ package org.hibernate.jpa.boot.spi;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import org.hibernate.cfg.Configuration;
/** /**
* Represents a 2-phase JPA bootstrap process for building a Hibernate EntityManagerFactory. * Represents a 2-phase JPA bootstrap process for building a Hibernate EntityManagerFactory.
* *
* The first phase is the process of instantiating this builder. During the first phase, loading of Class references * The first phase is the process of instantiating this builder. During the first phase, loading of Class references
* is highly discouraged. * is highly discouraged.
* *
* The second phase is building the EntityManagerFactory instance via {@link #buildEntityManagerFactory()}. * The second phase is building the EntityManagerFactory instance via {@link #build}.
* *
* If anything goes wrong during either phase and the bootstrap process needs to be aborted, {@link #cancel()} should * If anything goes wrong during either phase and the bootstrap process needs to be aborted, {@link #cancel()} should
* be called. * be called.
@ -42,12 +40,22 @@ import org.hibernate.cfg.Configuration;
* @author Scott Marlow * @author Scott Marlow
*/ */
public interface EntityManagerFactoryBuilder { public interface EntityManagerFactoryBuilder {
/**
* Allows passing in a Java EE ValidatorFactory (delayed from constructing the builder, AKA phase 2) to be used
* in building the EntityManagerFactory
*
* @param validatorFactory The ValidatorFactory
*
* @return {@code this}, for method chaining
*/
public EntityManagerFactoryBuilder withValidatorFactory(Object validatorFactory);
/** /**
* Build {@link EntityManagerFactory} instance * Build {@link EntityManagerFactory} instance
* *
* @return The built {@link EntityManagerFactory} * @return The built {@link EntityManagerFactory}
*/ */
public EntityManagerFactory buildEntityManagerFactory(); public EntityManagerFactory build();
/** /**
* Cancel the building processing. This is used to signal the builder to release any resources in the case of * Cancel the building processing. This is used to signal the builder to release any resources in the case of

View File

@ -93,7 +93,7 @@ public abstract class BaseEntityManagerFunctionalTestCase extends BaseUnitTestCa
entityManagerFactory = (EntityManagerFactoryImpl) Bootstrap.getEntityManagerFactoryBuilder( entityManagerFactory = (EntityManagerFactoryImpl) Bootstrap.getEntityManagerFactoryBuilder(
buildPersistenceUnitDescriptor(), buildPersistenceUnitDescriptor(),
buildSettings() buildSettings()
).buildEntityManagerFactory(); ).build();
serviceRegistry = (StandardServiceRegistryImpl) entityManagerFactory.getSessionFactory() serviceRegistry = (StandardServiceRegistryImpl) entityManagerFactory.getSessionFactory()
.getServiceRegistry() .getServiceRegistry()

View File

@ -46,6 +46,6 @@ public class TestingEntityManagerFactoryGenerator {
} }
public static EntityManagerFactory generateEntityManagerFactory(PersistenceUnitDescriptor descriptor, Map settings) { public static EntityManagerFactory generateEntityManagerFactory(PersistenceUnitDescriptor descriptor, Map settings) {
return Bootstrap.getEntityManagerFactoryBuilder( descriptor, settings ).buildEntityManagerFactory(); return Bootstrap.getEntityManagerFactoryBuilder( descriptor, settings ).build();
} }
} }

View File

@ -52,7 +52,7 @@ public class InterceptorTest {
public void testConfiguredInterceptor() { public void testConfiguredInterceptor() {
Map settings = basicSettings(); Map settings = basicSettings();
settings.put( AvailableSettings.INTERCEPTOR, ExceptionInterceptor.class.getName() ); settings.put( AvailableSettings.INTERCEPTOR, ExceptionInterceptor.class.getName() );
EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( new PersistenceUnitDescriptorAdapter(), settings ).buildEntityManagerFactory(); EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( new PersistenceUnitDescriptorAdapter(), settings ).build();
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
Item i = new Item(); Item i = new Item();
i.setName( "Laptop" ); i.setName( "Laptop" );
@ -78,7 +78,7 @@ public class InterceptorTest {
public void testConfiguredSessionInterceptor() { public void testConfiguredSessionInterceptor() {
Map settings = basicSettings(); Map settings = basicSettings();
settings.put( AvailableSettings.SESSION_INTERCEPTOR, LocalExceptionInterceptor.class.getName() ); settings.put( AvailableSettings.SESSION_INTERCEPTOR, LocalExceptionInterceptor.class.getName() );
EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( new PersistenceUnitDescriptorAdapter(), settings ).buildEntityManagerFactory(); EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( new PersistenceUnitDescriptorAdapter(), settings ).build();
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
Item i = new Item(); Item i = new Item();
i.setName( "Laptop" ); i.setName( "Laptop" );
@ -104,7 +104,7 @@ public class InterceptorTest {
public void testEmptyCreateEntityManagerFactoryAndPropertyUse() { public void testEmptyCreateEntityManagerFactoryAndPropertyUse() {
Map settings = basicSettings(); Map settings = basicSettings();
settings.put( AvailableSettings.INTERCEPTOR, ExceptionInterceptor.class.getName() ); settings.put( AvailableSettings.INTERCEPTOR, ExceptionInterceptor.class.getName() );
EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( new PersistenceUnitDescriptorAdapter(), settings ).buildEntityManagerFactory(); EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( new PersistenceUnitDescriptorAdapter(), settings ).build();
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
Item i = new Item(); Item i = new Item();
i.setName( "Laptop" ); i.setName( "Laptop" );
@ -130,7 +130,7 @@ public class InterceptorTest {
public void testOnLoadCallInInterceptor() { public void testOnLoadCallInInterceptor() {
Map settings = basicSettings(); Map settings = basicSettings();
settings.put( AvailableSettings.INTERCEPTOR, new ExceptionInterceptor( true ) ); settings.put( AvailableSettings.INTERCEPTOR, new ExceptionInterceptor( true ) );
EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( new PersistenceUnitDescriptorAdapter(), settings ).buildEntityManagerFactory(); EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( new PersistenceUnitDescriptorAdapter(), settings ).build();
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
Item i = new Item(); Item i = new Item();
i.setName( "Laptop" ); i.setName( "Laptop" );

View File

@ -80,7 +80,7 @@ public class PersisterClassProviderTest {
EntityManagerFactory entityManagerFactory = Bootstrap.getEntityManagerFactoryBuilder( EntityManagerFactory entityManagerFactory = Bootstrap.getEntityManagerFactoryBuilder(
new PersistenceUnitDescriptorAdapter(), new PersistenceUnitDescriptorAdapter(),
settings settings
).buildEntityManagerFactory(); ).build();
entityManagerFactory.close(); entityManagerFactory.close();
} }
catch ( PersistenceException e ) { catch ( PersistenceException e ) {

View File

@ -50,7 +50,7 @@ public class SessionFactoryObserverTest {
); );
try { try {
final EntityManagerFactory entityManagerFactory = builder.buildEntityManagerFactory(); final EntityManagerFactory entityManagerFactory = builder.build();
entityManagerFactory.close(); entityManagerFactory.close();
Assert.fail( "GoofyException should have been thrown" ); Assert.fail( "GoofyException should have been thrown" );
} }

View File

@ -51,7 +51,7 @@ public class IdentifierGeneratorStrategyProviderTest {
final EntityManagerFactory entityManagerFactory = Bootstrap.getEntityManagerFactoryBuilder( final EntityManagerFactory entityManagerFactory = Bootstrap.getEntityManagerFactoryBuilder(
new PersistenceUnitInfoAdapter(), new PersistenceUnitInfoAdapter(),
settings settings
).buildEntityManagerFactory(); ).build();
final EntityManager entityManager = entityManagerFactory.createEntityManager(); final EntityManager entityManager = entityManagerFactory.createEntityManager();
try { try {

View File

@ -97,7 +97,7 @@ public abstract class BaseEnversJPAFunctionalTestCase extends AbstractEnversTest
buildPersistenceUnitDescriptor(), buildPersistenceUnitDescriptor(),
buildSettings() buildSettings()
); );
entityManagerFactory = (EntityManagerFactoryImpl) entityManagerFactoryBuilder.buildEntityManagerFactory(); entityManagerFactory = (EntityManagerFactoryImpl) entityManagerFactoryBuilder.build();
serviceRegistry = (StandardServiceRegistryImpl) entityManagerFactory.getSessionFactory() serviceRegistry = (StandardServiceRegistryImpl) entityManagerFactory.getSessionFactory()
.getServiceRegistry() .getServiceRegistry()

View File

@ -116,7 +116,7 @@ public abstract class AbstractEntityManagerTest extends AbstractEnversTest {
configurationProperties configurationProperties
); );
emf = (EntityManagerFactoryImpl) entityManagerFactoryBuilder.buildEntityManagerFactory(); emf = (EntityManagerFactoryImpl) entityManagerFactoryBuilder.build();
serviceRegistry = (StandardServiceRegistryImpl) emf.getSessionFactory().getServiceRegistry().getParentServiceRegistry(); serviceRegistry = (StandardServiceRegistryImpl) emf.getSessionFactory().getServiceRegistry().getParentServiceRegistry();