Skip to content

Commit 9f460e1

Browse files
committed
HHH-14432 Implement cleanup for EntityManagerFactoryBuilderImpl to close connections on bootstrap errors
1 parent 21c8924 commit 9f460e1

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.hibernate.cfg.AttributeConverterDefinition;
5555
import org.hibernate.cfg.Environment;
5656
import org.hibernate.cfg.beanvalidation.BeanValidationIntegrator;
57+
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
5758
import org.hibernate.engine.spi.SessionFactoryImplementor;
5859
import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory;
5960
import org.hibernate.integrator.spi.Integrator;
@@ -77,7 +78,9 @@
7778
import org.hibernate.secure.spi.GrantedPermission;
7879
import org.hibernate.secure.spi.JaccPermissionDeclarations;
7980
import org.hibernate.service.ServiceRegistry;
81+
import org.hibernate.service.spi.ServiceBinding;
8082
import org.hibernate.service.spi.ServiceRegistryImplementor;
83+
import org.hibernate.service.spi.Stoppable;
8184
import org.hibernate.tool.schema.spi.DelayedDropRegistryNotAvailableImpl;
8285
import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator;
8386

@@ -1213,9 +1216,24 @@ public EntityManagerFactoryBuilder withDataSource(DataSource dataSource) {
12131216

12141217
@Override
12151218
public void cancel() {
1219+
cleanup();
12161220
// todo : close the bootstrap registry (not critical, but nice to do)
12171221
}
12181222

1223+
private void cleanup() {
1224+
// Stop and de-register the ConnectionProvider to prevent connections lying around
1225+
if ( standardServiceRegistry instanceof ServiceRegistryImplementor &&
1226+
standardServiceRegistry instanceof ServiceBinding.ServiceLifecycleOwner ) {
1227+
final ServiceRegistryImplementor serviceRegistry = (ServiceRegistryImplementor) standardServiceRegistry;
1228+
final ServiceBinding.ServiceLifecycleOwner lifecycleOwner = (ServiceBinding.ServiceLifecycleOwner) serviceRegistry;
1229+
final ServiceBinding<ConnectionProvider> binding = serviceRegistry.locateServiceBinding( ConnectionProvider.class );
1230+
if ( binding != null && binding.getService() instanceof Stoppable ) {
1231+
lifecycleOwner.stopService( binding );
1232+
binding.setService( null );
1233+
}
1234+
}
1235+
}
1236+
12191237
/**
12201238
* Used by extensions : Hibernate Reactive
12211239
*/
@@ -1245,21 +1263,32 @@ public void generateSchema() {
12451263
catch (Exception e) {
12461264
throw persistenceException( "Error performing schema management", e );
12471265
}
1248-
1249-
// release this builder
1250-
cancel();
1266+
finally {
1267+
// release this builder
1268+
cancel();
1269+
}
12511270
}
12521271

12531272
@Override
12541273
public EntityManagerFactory build() {
1255-
final SessionFactoryBuilder sfBuilder = metadata().getSessionFactoryBuilder();
1256-
populateSfBuilder( sfBuilder, standardServiceRegistry );
1257-
1274+
boolean success = false;
12581275
try {
1259-
return sfBuilder.build();
1276+
final SessionFactoryBuilder sfBuilder = metadata().getSessionFactoryBuilder();
1277+
populateSfBuilder( sfBuilder, standardServiceRegistry );
1278+
1279+
try {
1280+
final EntityManagerFactory emf = sfBuilder.build();
1281+
success = true;
1282+
return emf;
1283+
}
1284+
catch (Exception e) {
1285+
throw persistenceException( "Unable to build Hibernate SessionFactory", e );
1286+
}
12601287
}
1261-
catch (Exception e) {
1262-
throw persistenceException( "Unable to build Hibernate SessionFactory", e );
1288+
finally {
1289+
if ( !success ) {
1290+
cleanup();
1291+
}
12631292
}
12641293
}
12651294

hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/DdlTransactionIsolatorJtaImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public class DdlTransactionIsolatorJtaImpl implements DdlTransactionIsolator {
2929

3030
private final JdbcContext jdbcContext;
3131

32-
private Transaction suspendedTransaction;
33-
private Connection jdbcConnection;
32+
private final Transaction suspendedTransaction;
33+
private final Connection jdbcConnection;
3434

3535
public DdlTransactionIsolatorJtaImpl(JdbcContext jdbcContext) {
3636
this.jdbcContext = jdbcContext;

0 commit comments

Comments
 (0)