diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/StandardServiceRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/StandardServiceRegistryImpl.java index ca74699daa..3ee764ab36 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/StandardServiceRegistryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/StandardServiceRegistryImpl.java @@ -71,14 +71,20 @@ public class StandardServiceRegistryImpl extends AbstractServiceRegistryImpl imp this.configurationValues = configurationValues; - // process initiators - for ( ServiceInitiator initiator : serviceInitiators ) { - createServiceBinding( initiator ); - } + try { + // process initiators + for ( ServiceInitiator initiator : serviceInitiators ) { + createServiceBinding( initiator ); + } - // then, explicitly provided service instances - for ( ProvidedService providedService : providedServices ) { - createServiceBinding( providedService ); + // then, explicitly provided service instances + for ( ProvidedService providedService : providedServices ) { + createServiceBinding( providedService ); + } + } + catch (RuntimeException e) { + visitServiceBindings( binding -> binding.getLifecycleOwner().stopService( binding ) ); + throw e; } } diff --git a/hibernate-core/src/main/java/org/hibernate/service/internal/AbstractServiceRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/service/internal/AbstractServiceRegistryImpl.java index 418745b07e..422717dc8a 100644 --- a/hibernate-core/src/main/java/org/hibernate/service/internal/AbstractServiceRegistryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/service/internal/AbstractServiceRegistryImpl.java @@ -14,6 +14,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; import org.hibernate.boot.registry.BootstrapServiceRegistry; import org.hibernate.cfg.Environment; @@ -126,6 +127,10 @@ public abstract class AbstractServiceRegistryImpl registerService( binding, providedService.getService() ); } + protected void visitServiceBindings(Consumer action) { + serviceBindingList.forEach( action ); + } + @Override @SuppressWarnings( {"unchecked"}) public ServiceRegistry getParentServiceRegistry() { diff --git a/hibernate-core/src/test/java/org/hibernate/service/ServiceContributorTest.java b/hibernate-core/src/test/java/org/hibernate/service/ServiceContributorTest.java new file mode 100644 index 0000000000..b242a71b1f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/service/ServiceContributorTest.java @@ -0,0 +1,54 @@ +/* + * 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.service; + +import java.util.Map; + +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cache.internal.RegionFactoryInitiator; +import org.hibernate.cache.spi.RegionFactory; +import org.hibernate.service.spi.ServiceRegistryImplementor; + +import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +/** + * @author Steve Ebersole + */ +public class ServiceContributorTest extends BaseUnitTestCase { + @Test + public void overrideInitiator() { + StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder(); + + class MyRegionFactoryInitiator extends RegionFactoryInitiator { + private boolean called = false; + + @Override + public RegionFactory initiateService( + Map configurationValues, + ServiceRegistryImplementor registry) { + called = true; + return super.initiateService( configurationValues, registry ); + } + } + + final MyRegionFactoryInitiator initiator = new MyRegionFactoryInitiator(); + + ssrb.addInitiator( initiator ); + + final ServiceRegistryImplementor registry = (ServiceRegistryImplementor) ssrb.build(); + try { + registry.getService( RegionFactory.class ); + assertTrue( initiator.called ); + } + finally { + StandardServiceRegistryBuilder.destroy( registry ); + } + } +}