HHH-12417 - default strategy based on registrations with StrategySelector

ConnectionProviderInitiator and tests
This commit is contained in:
Steve Ebersole 2018-03-21 19:23:38 -05:00
parent 953f956989
commit 1174cdad65
7 changed files with 172 additions and 16 deletions

View File

@ -146,5 +146,5 @@ public interface StrategySelector extends Service {
* to allow defaulting the choice to the single registered implementor when * to allow defaulting the choice to the single registered implementor when
* only one is registered * only one is registered
*/ */
<T> Collection<T> getRegisteredStrategyImplementors(Class<T> strategy); <T> Collection<Class<? extends T>> getRegisteredStrategyImplementors(Class<T> strategy);
} }

View File

@ -77,9 +77,11 @@ public class RegionFactoryInitiator implements StandardServiceInitiator<RegionFa
boolean allowDefaulting = true; boolean allowDefaulting = true;
if ( allowDefaulting ) { if ( allowDefaulting ) {
final StrategySelector selector = registry.getService( StrategySelector.class ); final StrategySelector selector = registry.getService( StrategySelector.class );
final Collection<RegionFactory> implementors = selector.getRegisteredStrategyImplementors( RegionFactory.class ); final Collection<Class<? extends RegionFactory>> implementors = selector.getRegisteredStrategyImplementors( RegionFactory.class );
if ( implementors != null && implementors.size() == 1 ) { if ( implementors != null && implementors.size() == 1 ) {
regionFactory = selector.resolveStrategy( RegionFactory.class, implementors.iterator().next() ); regionFactory = selector.resolveStrategy( RegionFactory.class, implementors.iterator().next() );
configurationValues.put( AvailableSettings.CACHE_REGION_FACTORY, regionFactory );
configurationValues.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, "true" );
} }
else { else {
LOG.debugf( "Cannot default RegionFactory based on registered strategies as `%s` RegionFactory strategies were registered" ); LOG.debugf( "Cannot default RegionFactory based on registered strategies as `%s` RegionFactory strategies were registered" );

View File

@ -10,6 +10,7 @@ import java.beans.BeanInfo;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.sql.Connection; import java.sql.Connection;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -122,20 +123,31 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
return instantiateExplicitConnectionProvider( providerClass ); return instantiateExplicitConnectionProvider( providerClass );
} }
else { else {
String providerName = explicitSetting.toString(); String providerName = StringHelper.nullIfEmpty( explicitSetting.toString() );
if ( LEGACY_CONNECTION_PROVIDER_MAPPING.containsKey( providerName ) ) { if ( providerName != null ) {
final String actualProviderName = LEGACY_CONNECTION_PROVIDER_MAPPING.get( providerName ); if ( LEGACY_CONNECTION_PROVIDER_MAPPING.containsKey( providerName ) ) {
DeprecationLogger.DEPRECATION_LOGGER.connectionProviderClassDeprecated( providerName, actualProviderName ); final String actualProviderName = LEGACY_CONNECTION_PROVIDER_MAPPING.get( providerName );
providerName = actualProviderName; DeprecationLogger.DEPRECATION_LOGGER.connectionProviderClassDeprecated(
} providerName,
actualProviderName
);
providerName = actualProviderName;
}
LOG.instantiatingExplicitConnectionProvider( providerName ); LOG.instantiatingExplicitConnectionProvider( providerName );
final Class providerClass = strategySelector.selectStrategyImplementor( ConnectionProvider.class, providerName ); final Class providerClass = strategySelector.selectStrategyImplementor(
try { ConnectionProvider.class,
return instantiateExplicitConnectionProvider( providerClass ); providerName
} );
catch (Exception e) { try {
throw new HibernateException( "Could not instantiate connection provider [" + providerName + "]", e ); return instantiateExplicitConnectionProvider( providerClass );
}
catch (Exception e) {
throw new HibernateException(
"Could not instantiate connection provider [" + providerName + "]",
e
);
}
} }
} }
} }
@ -146,6 +158,16 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
ConnectionProvider connectionProvider = null; ConnectionProvider connectionProvider = null;
final Class<? extends ConnectionProvider> singleRegisteredProvider = getSingleRegisteredProvider( strategySelector );
if ( singleRegisteredProvider != null ) {
try {
connectionProvider = singleRegisteredProvider.newInstance();
}
catch (IllegalAccessException | InstantiationException e) {
throw new HibernateException( "Could not instantiate singular-registered ConnectionProvider", e );
}
}
if ( connectionProvider == null ) { if ( connectionProvider == null ) {
if ( c3p0ConfigDefined( configurationValues ) ) { if ( c3p0ConfigDefined( configurationValues ) ) {
connectionProvider = instantiateC3p0Provider( strategySelector ); connectionProvider = instantiateC3p0Provider( strategySelector );
@ -214,6 +236,15 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
return connectionProvider; return connectionProvider;
} }
private Class<? extends ConnectionProvider> getSingleRegisteredProvider(StrategySelector strategySelector) {
final Collection<Class<? extends ConnectionProvider>> implementors = strategySelector.getRegisteredStrategyImplementors( ConnectionProvider.class );
if ( implementors != null && implementors.size() == 1 ) {
return implementors.iterator().next();
}
return null;
}
private ConnectionProvider instantiateExplicitConnectionProvider(Class providerClass) { private ConnectionProvider instantiateExplicitConnectionProvider(Class providerClass) {
try { try {
return (ConnectionProvider) providerClass.newInstance(); return (ConnectionProvider) providerClass.newInstance();

View File

@ -9,7 +9,9 @@ package org.hibernate.engine.spi;
import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.internal.DisabledCaching; import org.hibernate.cache.internal.DisabledCaching;
import org.hibernate.cache.internal.EnabledCaching; import org.hibernate.cache.internal.EnabledCaching;
import org.hibernate.cache.internal.NoCachingRegionFactory;
import org.hibernate.cache.spi.CacheImplementor; import org.hibernate.cache.spi.CacheImplementor;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceInitiator; import org.hibernate.service.spi.SessionFactoryServiceInitiator;
@ -27,7 +29,8 @@ public class CacheInitiator implements SessionFactoryServiceInitiator<CacheImple
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
SessionFactoryOptions sessionFactoryOptions, SessionFactoryOptions sessionFactoryOptions,
ServiceRegistryImplementor registry) { ServiceRegistryImplementor registry) {
return sessionFactoryOptions.isSecondLevelCacheEnabled() final RegionFactory regionFactory = registry.getService( RegionFactory.class );
return ( ! NoCachingRegionFactory.class.isInstance( regionFactory ) )
? new EnabledCaching( sessionFactory ) ? new EnabledCaching( sessionFactory )
: new DisabledCaching( sessionFactory ); : new DisabledCaching( sessionFactory );
} }

View File

@ -0,0 +1,75 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.test.cache;
import java.util.Collection;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.cache.internal.EnabledCaching;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.testing.cache.CachingRegionFactory;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Steve Ebersole
*/
public class SingleRegisteredProviderTest extends BaseNonConfigCoreFunctionalTestCase {
@Override
protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) {
super.configureStandardServiceRegistryBuilder( ssrb );
ssrb.applySetting( AvailableSettings.USE_SECOND_LEVEL_CACHE, "false" );
ssrb.applySetting( AvailableSettings.CACHE_REGION_PREFIX, "" );
ssrb.applySetting( AvailableSettings.CACHE_REGION_FACTORY, "" );
ssrb.applySetting( AvailableSettings.CONNECTION_PROVIDER, "" );
}
@Override
protected void configureBootstrapServiceRegistryBuilder(BootstrapServiceRegistryBuilder bsrb) {
super.configureBootstrapServiceRegistryBuilder( bsrb );
bsrb.applyStrategySelector( ConnectionProvider.class, "testing", DriverManagerConnectionProviderImpl.class );
}
@Test
public void testCachingExpectations() {
final Collection<Class<? extends RegionFactory>> implementors = sessionFactory().getServiceRegistry()
.getService( StrategySelector.class )
.getRegisteredStrategyImplementors( RegionFactory.class );
assertThat( implementors.size(), equalTo( 1 ) );
assertThat( sessionFactory().getSessionFactoryOptions().isSecondLevelCacheEnabled(), equalTo( true ) );
assertThat( sessionFactory().getCache(), instanceOf( EnabledCaching.class ) );
assertThat( sessionFactory().getCache().getRegionFactory(), instanceOf( CachingRegionFactory.class ) );
assertThat( implementors.iterator().next(), equalTo( CachingRegionFactory.class ) );
}
@Test
public void testConnectionsExpectations() {
final Collection<Class<? extends ConnectionProvider>> implementors = sessionFactory().getServiceRegistry()
.getService( StrategySelector.class )
.getRegisteredStrategyImplementors( ConnectionProvider.class );
assertThat( implementors.size(), equalTo( 1 ) );
final ConnectionProvider configuredProvider = sessionFactory().getServiceRegistry().getService( ConnectionProvider.class );
assertThat( configuredProvider, instanceOf( DriverManagerConnectionProviderImpl.class ) );
assertThat( implementors.iterator().next(), equalTo( DriverManagerConnectionProviderImpl.class ) );
}
}

View File

@ -0,0 +1,38 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.testing.cache;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl;
import org.hibernate.boot.registry.selector.StrategyRegistration;
import org.hibernate.boot.registry.selector.StrategyRegistrationProvider;
import org.hibernate.cache.spi.RegionFactory;
/**
* Makes the JCache RegionFactory available to the Hibernate
* {@link org.hibernate.boot.registry.selector.spi.StrategySelector} service
* under a number of keys. Prefer to use
*
* @author Steve Ebersole
*/
public class StrategyRegistrationProviderImpl implements StrategyRegistrationProvider {
@Override
@SuppressWarnings("unchecked")
public Iterable<StrategyRegistration> getStrategyRegistrations() {
return Collections.singletonList(
new SimpleStrategyRegistrationImpl(
RegionFactory.class,
CachingRegionFactory.class,
"testing",
CachingRegionFactory.class.getName()
)
);
}
}

View File

@ -0,0 +1,7 @@
#
# Hibernate, Relational Persistence for Idiomatic Java
#
# License: GNU Lesser General Public License (LGPL), version 2.1 or later
# See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
org.hibernate.testing.cache.StrategyRegistrationProviderImpl