HHH-8619 - Account for "shadow" services as part of ServiceRegistry impls
This commit is contained in:
parent
c88494698e
commit
859eaaa1c5
|
@ -56,6 +56,7 @@ import org.hibernate.engine.loading.internal.EntityLoadContext;
|
||||||
import org.hibernate.engine.spi.CollectionKey;
|
import org.hibernate.engine.spi.CollectionKey;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.id.IntegralDataTypeHolder;
|
import org.hibernate.id.IntegralDataTypeHolder;
|
||||||
|
import org.hibernate.service.Service;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.SerializationException;
|
import org.hibernate.type.SerializationException;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -1629,4 +1630,11 @@ public interface CoreMessageLogger extends BasicLogger {
|
||||||
"using 'key'/'value' as required by spec; attempting to DoTheRightThing"
|
"using 'key'/'value' as required by spec; attempting to DoTheRightThing"
|
||||||
)
|
)
|
||||||
void nonCompliantMapConversion(String collectionRole);
|
void nonCompliantMapConversion(String collectionRole);
|
||||||
|
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(
|
||||||
|
id = 450,
|
||||||
|
value = "Encountered request for Service by non-primary service role [%s -> %s]; please update usage"
|
||||||
|
)
|
||||||
|
void alternateServiceRole(String requestedRole, String targetRole);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,12 @@ import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||||
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.service.Service;
|
import org.hibernate.service.Service;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.service.UnknownServiceException;
|
import org.hibernate.service.UnknownServiceException;
|
||||||
|
@ -48,19 +49,22 @@ import org.hibernate.service.spi.Startable;
|
||||||
import org.hibernate.service.spi.Stoppable;
|
import org.hibernate.service.spi.Stoppable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Basic implementation of the ServiceRegistry and ServiceRegistryImplementor contracts
|
||||||
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractServiceRegistryImpl
|
public abstract class AbstractServiceRegistryImpl
|
||||||
implements ServiceRegistryImplementor, ServiceBinding.ServiceLifecycleOwner {
|
implements ServiceRegistryImplementor, ServiceBinding.ServiceLifecycleOwner {
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
private static final CoreMessageLogger log = CoreLogging.messageLogger( AbstractServiceRegistryImpl.class );
|
||||||
CoreMessageLogger.class,
|
|
||||||
AbstractServiceRegistryImpl.class.getName()
|
public static final String ALLOW_CRAWLING = "hibernate.service.allow_crawling";
|
||||||
);
|
|
||||||
|
|
||||||
private final ServiceRegistryImplementor parent;
|
private final ServiceRegistryImplementor parent;
|
||||||
|
private final boolean allowCrawling;
|
||||||
|
|
||||||
private final ConcurrentHashMap<Class,ServiceBinding> serviceBindingMap = CollectionHelper.concurrentMap( 20 );
|
private final ConcurrentHashMap<Class,ServiceBinding> serviceBindingMap = CollectionHelper.concurrentMap( 20 );
|
||||||
|
private ConcurrentHashMap<Class,Class> roleXref;
|
||||||
|
|
||||||
// IMPL NOTE : the list used for ordered destruction. Cannot used map above because we need to
|
// IMPL NOTE : the list used for ordered destruction. Cannot used map above because we need to
|
||||||
// iterate it in reverse order which is only available through ListIterator
|
// iterate it in reverse order which is only available through ListIterator
|
||||||
|
@ -74,13 +78,15 @@ public abstract class AbstractServiceRegistryImpl
|
||||||
|
|
||||||
protected AbstractServiceRegistryImpl(ServiceRegistryImplementor parent) {
|
protected AbstractServiceRegistryImpl(ServiceRegistryImplementor parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.allowCrawling = ConfigurationHelper.getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractServiceRegistryImpl(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
public AbstractServiceRegistryImpl(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||||
if ( ! ServiceRegistryImplementor.class.isInstance( bootstrapServiceRegistry ) ) {
|
if ( ! ServiceRegistryImplementor.class.isInstance( bootstrapServiceRegistry ) ) {
|
||||||
throw new IllegalArgumentException( "Boot-strap registry was not " );
|
throw new IllegalArgumentException( "ServiceRegistry parent needs to implement ServiceRegistryImplementor" );
|
||||||
}
|
}
|
||||||
this.parent = (ServiceRegistryImplementor) bootstrapServiceRegistry;
|
this.parent = (ServiceRegistryImplementor) bootstrapServiceRegistry;
|
||||||
|
this.allowCrawling = ConfigurationHelper.getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked" })
|
@SuppressWarnings({ "unchecked" })
|
||||||
|
@ -117,9 +123,49 @@ public abstract class AbstractServiceRegistryImpl
|
||||||
// look in parent
|
// look in parent
|
||||||
serviceBinding = parent.locateServiceBinding( serviceRole );
|
serviceBinding = parent.locateServiceBinding( serviceRole );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( serviceBinding != null ) {
|
||||||
return serviceBinding;
|
return serviceBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !allowCrawling ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// look for a previously resolved alternate registration
|
||||||
|
if ( roleXref != null ) {
|
||||||
|
if ( roleXref.containsKey( serviceRole ) ) {
|
||||||
|
return serviceBindingMap.get( roleXref.get( serviceRole ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform a crawl looking for an alternate registration
|
||||||
|
for ( ServiceBinding binding : serviceBindingMap.values() ) {
|
||||||
|
if ( serviceRole.isAssignableFrom( binding.getServiceRole() ) ) {
|
||||||
|
// we found an alternate...
|
||||||
|
log.alternateServiceRole( serviceRole.getName(), binding.getServiceRole().getName() );
|
||||||
|
registerAlternate( serviceRole, binding.getServiceRole() );
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( binding.getService() != null && serviceRole.isInstance( binding.getService() ) ) {
|
||||||
|
// we found an alternate...
|
||||||
|
log.alternateServiceRole( serviceRole.getName(), binding.getServiceRole().getName() );
|
||||||
|
registerAlternate( serviceRole, binding.getServiceRole() );
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerAlternate(Class alternate, Class target) {
|
||||||
|
if ( roleXref == null ) {
|
||||||
|
roleXref = CollectionHelper.concurrentMap( 20 );
|
||||||
|
}
|
||||||
|
roleXref.put( alternate, target );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R extends Service> R getService(Class<R> serviceRole) {
|
public <R extends Service> R getService(Class<R> serviceRole) {
|
||||||
final ServiceBinding<R> serviceBinding = locateServiceBinding( serviceRole );
|
final ServiceBinding<R> serviceBinding = locateServiceBinding( serviceRole );
|
||||||
|
@ -143,8 +189,8 @@ public abstract class AbstractServiceRegistryImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
private <R extends Service> R initializeService(ServiceBinding<R> serviceBinding) {
|
private <R extends Service> R initializeService(ServiceBinding<R> serviceBinding) {
|
||||||
if ( LOG.isTraceEnabled() ) {
|
if ( log.isTraceEnabled() ) {
|
||||||
LOG.tracev( "Initializing service [role={0}]", serviceBinding.getServiceRole().getName() );
|
log.tracev( "Initializing service [role={0}]", serviceBinding.getServiceRole().getName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// PHASE 1 : create service
|
// PHASE 1 : create service
|
||||||
|
@ -211,7 +257,7 @@ public abstract class AbstractServiceRegistryImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (NullPointerException e) {
|
catch (NullPointerException e) {
|
||||||
LOG.error("NPE injecting service deps : " + service.getClass().getName());
|
log.error( "NPE injecting service deps : " + service.getClass().getName() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +331,7 @@ public abstract class AbstractServiceRegistryImpl
|
||||||
( (Stoppable) service ).stop();
|
( (Stoppable) service ).stop();
|
||||||
}
|
}
|
||||||
catch ( Exception e ) {
|
catch ( Exception e ) {
|
||||||
LOG.unableToStopService( service.getClass(), e.toString() );
|
log.unableToStopService( service.getClass(), e.toString() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,3 +40,4 @@ hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFa
|
||||||
hibernate.jdbc.batch_versioned_data true
|
hibernate.jdbc.batch_versioned_data true
|
||||||
|
|
||||||
javax.persistence.validation.mode=NONE
|
javax.persistence.validation.mode=NONE
|
||||||
|
hibernate.service.allow_crawling=false
|
|
@ -32,3 +32,4 @@ hibernate.cache.region_prefix hibernate.test
|
||||||
|
|
||||||
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
|
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
|
||||||
hibernate.jdbc.batch_versioned_data true
|
hibernate.jdbc.batch_versioned_data true
|
||||||
|
hibernate.service.allow_crawling=false
|
|
@ -40,3 +40,4 @@ hibernate.jdbc.batch_size 0
|
||||||
|
|
||||||
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
|
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
|
||||||
hibernate.jdbc.batch_versioned_data true
|
hibernate.jdbc.batch_versioned_data true
|
||||||
|
hibernate.service.allow_crawling=false
|
||||||
|
|
|
@ -37,3 +37,4 @@ hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFa
|
||||||
|
|
||||||
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
|
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
|
||||||
hibernate.jdbc.batch_versioned_data true
|
hibernate.jdbc.batch_versioned_data true
|
||||||
|
hibernate.service.allow_crawling=false
|
||||||
|
|
|
@ -1,26 +1,4 @@
|
||||||
################################################################################
|
|
||||||
# Hibernate, Relational Persistence for Idiomatic Java #
|
|
||||||
# #
|
|
||||||
# Copyright (c) 2007, Red Hat, Inc. and/or it's affiliates 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. and/or it's affiliates. #
|
|
||||||
# #
|
|
||||||
# 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 #
|
|
||||||
################################################################################
|
|
||||||
hibernate.dialect org.hibernate.dialect.H2Dialect
|
hibernate.dialect org.hibernate.dialect.H2Dialect
|
||||||
hibernate.connection.driver_class org.h2.Driver
|
hibernate.connection.driver_class org.h2.Driver
|
||||||
hibernate.connection.url jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE
|
hibernate.connection.url jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE
|
||||||
|
@ -37,3 +15,4 @@ hibernate.generate_statistics true
|
||||||
|
|
||||||
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
|
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
|
||||||
hibernate.jdbc.batch_versioned_data true
|
hibernate.jdbc.batch_versioned_data true
|
||||||
|
hibernate.service.allow_crawling=false
|
||||||
|
|
Loading…
Reference in New Issue