Skip to content

Commit 0af8755

Browse files
beikovjrenaat
authored andcommitted
Backport of changes from 6314395 on
wip/6.0 (Fix connection leaks by properly closing service registries)
1 parent e0d262c commit 0af8755

File tree

65 files changed

+1226
-1066
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1226
-1066
lines changed

hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,14 @@ public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throw
741741
public SessionFactory buildSessionFactory() throws HibernateException {
742742
log.debug( "Building session factory using internal StandardServiceRegistryBuilder" );
743743
standardServiceRegistryBuilder.applySettings( properties );
744-
return buildSessionFactory( standardServiceRegistryBuilder.build() );
744+
StandardServiceRegistry serviceRegistry = standardServiceRegistryBuilder.build();
745+
try {
746+
return buildSessionFactory( serviceRegistry );
747+
}
748+
catch (Throwable t) {
749+
serviceRegistry.close();
750+
throw t;
751+
}
745752
}
746753

747754

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

Lines changed: 67 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
3434
import org.hibernate.boot.cfgxml.spi.LoadedConfig;
3535
import org.hibernate.boot.cfgxml.spi.MappingReference;
36+
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
3637
import org.hibernate.boot.model.process.spi.ManagedResources;
3738
import org.hibernate.boot.model.process.spi.MetadataBuildingProcess;
3839
import org.hibernate.boot.registry.BootstrapServiceRegistry;
@@ -222,80 +223,87 @@ private EntityManagerFactoryBuilderImpl(
222223
providedClassLoader,
223224
providedClassLoaderService
224225
);
226+
try {
227+
// merge configuration sources and build the "standard" service registry
228+
final StandardServiceRegistryBuilder ssrBuilder = getStandardServiceRegistryBuilder( bsr );
225229

226-
// merge configuration sources and build the "standard" service registry
227-
final StandardServiceRegistryBuilder ssrBuilder = getStandardServiceRegistryBuilder( bsr );
228-
229-
final MergedSettings mergedSettings = mergeSettings( persistenceUnit, integrationSettings, ssrBuilder );
230+
final MergedSettings mergedSettings = mergeSettings( persistenceUnit, integrationSettings, ssrBuilder );
230231

231-
// flush before completion validation
232-
if ( "true".equals( mergedSettings.configurationValues.get( Environment.FLUSH_BEFORE_COMPLETION ) ) ) {
233-
LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION );
234-
mergedSettings.configurationValues.put( Environment.FLUSH_BEFORE_COMPLETION, "false" );
235-
}
232+
// flush before completion validation
233+
if ( "true".equals( mergedSettings.configurationValues.get( Environment.FLUSH_BEFORE_COMPLETION ) ) ) {
234+
LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION );
235+
mergedSettings.configurationValues.put( Environment.FLUSH_BEFORE_COMPLETION, "false" );
236+
}
236237

237-
// keep the merged config values for phase-2
238-
this.configurationValues = mergedSettings.getConfigurationValues();
238+
// keep the merged config values for phase-2
239+
this.configurationValues = mergedSettings.getConfigurationValues();
239240

240-
// Build the "standard" service registry
241-
ssrBuilder.applySettings( configurationValues );
241+
// Build the "standard" service registry
242+
ssrBuilder.applySettings( configurationValues );
242243

243-
this.standardServiceRegistry = ssrBuilder.build();
244+
this.standardServiceRegistry = ssrBuilder.build();
244245

245-
configureIdentifierGenerators( standardServiceRegistry );
246+
configureIdentifierGenerators( standardServiceRegistry );
246247

247-
final MetadataSources metadataSources = new MetadataSources( bsr );
248-
List<AttributeConverterDefinition> attributeConverterDefinitions = applyMappingResources( metadataSources );
248+
final MetadataSources metadataSources = new MetadataSources( bsr );
249+
this.metamodelBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder( standardServiceRegistry );
250+
List<AttributeConverterDefinition> attributeConverterDefinitions = applyMappingResources( metadataSources );
249251

250-
this.metamodelBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder( standardServiceRegistry );
251-
applyMetamodelBuilderSettings( mergedSettings, attributeConverterDefinitions );
252+
applyMetamodelBuilderSettings( mergedSettings, attributeConverterDefinitions );
252253

253-
applyMetadataBuilderContributor();
254+
applyMetadataBuilderContributor();
254255

255-
// todo : would be nice to have MetadataBuilder still do the handling of CfgXmlAccessService here
256-
// another option is to immediately handle them here (probably in mergeSettings?) as we encounter them...
257-
final CfgXmlAccessService cfgXmlAccessService = standardServiceRegistry.getService( CfgXmlAccessService.class );
258-
if ( cfgXmlAccessService.getAggregatedConfig() != null ) {
259-
if ( cfgXmlAccessService.getAggregatedConfig().getMappingReferences() != null ) {
260-
for ( MappingReference mappingReference : cfgXmlAccessService.getAggregatedConfig().getMappingReferences() ) {
261-
mappingReference.apply( metadataSources );
256+
// todo : would be nice to have MetadataBuilder still do the handling of CfgXmlAccessService here
257+
// another option is to immediately handle them here (probably in mergeSettings?) as we encounter them...
258+
final CfgXmlAccessService cfgXmlAccessService = standardServiceRegistry.getService( CfgXmlAccessService.class );
259+
if ( cfgXmlAccessService.getAggregatedConfig() != null ) {
260+
if ( cfgXmlAccessService.getAggregatedConfig().getMappingReferences() != null ) {
261+
for ( MappingReference mappingReference : cfgXmlAccessService.getAggregatedConfig()
262+
.getMappingReferences() ) {
263+
mappingReference.apply( metadataSources );
264+
}
262265
}
263266
}
264-
}
265267

266-
this.managedResources = MetadataBuildingProcess.prepare(
267-
metadataSources,
268-
metamodelBuilder.getBootstrapContext()
269-
);
268+
this.managedResources = MetadataBuildingProcess.prepare(
269+
metadataSources,
270+
metamodelBuilder.getBootstrapContext()
271+
);
270272

271-
final Object validatorFactory = configurationValues.get( org.hibernate.cfg.AvailableSettings.JPA_VALIDATION_FACTORY );
272-
if ( validatorFactory == null ) {
273-
withValidatorFactory( configurationValues.get( org.hibernate.cfg.AvailableSettings.JAKARTA_JPA_VALIDATION_FACTORY ) );
274-
}
275-
else {
276-
withValidatorFactory( validatorFactory );
277-
}
273+
final Object validatorFactory = configurationValues.get( org.hibernate.cfg.AvailableSettings.JPA_VALIDATION_FACTORY );
274+
if ( validatorFactory == null ) {
275+
withValidatorFactory( configurationValues.get( org.hibernate.cfg.AvailableSettings.JAKARTA_JPA_VALIDATION_FACTORY ) );
276+
}
277+
else {
278+
withValidatorFactory( validatorFactory );
279+
}
278280

279-
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
280-
// push back class transformation to the environment; for the time being this only has any effect in EE
281-
// container situations, calling back into PersistenceUnitInfo#addClassTransformer
281+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
282+
// push back class transformation to the environment; for the time being this only has any effect in EE
283+
// container situations, calling back into PersistenceUnitInfo#addClassTransformer
282284

283-
final boolean dirtyTrackingEnabled = readBooleanConfigurationValue( AvailableSettings.ENHANCER_ENABLE_DIRTY_TRACKING );
284-
final boolean lazyInitializationEnabled = readBooleanConfigurationValue( AvailableSettings.ENHANCER_ENABLE_LAZY_INITIALIZATION );
285-
final boolean associationManagementEnabled = readBooleanConfigurationValue( AvailableSettings.ENHANCER_ENABLE_ASSOCIATION_MANAGEMENT );
285+
final boolean dirtyTrackingEnabled = readBooleanConfigurationValue( AvailableSettings.ENHANCER_ENABLE_DIRTY_TRACKING );
286+
final boolean lazyInitializationEnabled = readBooleanConfigurationValue( AvailableSettings.ENHANCER_ENABLE_LAZY_INITIALIZATION );
287+
final boolean associationManagementEnabled = readBooleanConfigurationValue( AvailableSettings.ENHANCER_ENABLE_ASSOCIATION_MANAGEMENT );
286288

287-
if ( dirtyTrackingEnabled || lazyInitializationEnabled || associationManagementEnabled ) {
288-
EnhancementContext enhancementContext = getEnhancementContext(
289-
dirtyTrackingEnabled,
290-
lazyInitializationEnabled,
291-
associationManagementEnabled
292-
);
289+
if ( dirtyTrackingEnabled || lazyInitializationEnabled || associationManagementEnabled ) {
290+
EnhancementContext enhancementContext = getEnhancementContext(
291+
dirtyTrackingEnabled,
292+
lazyInitializationEnabled,
293+
associationManagementEnabled
294+
);
293295

294-
persistenceUnit.pushClassTransformer( enhancementContext );
295-
}
296+
persistenceUnit.pushClassTransformer( enhancementContext );
297+
}
296298

297-
// for the time being we want to revoke access to the temp ClassLoader if one was passed
298-
metamodelBuilder.applyTempClassLoader( null );
299+
// for the time being we want to revoke access to the temp ClassLoader if one was passed
300+
metamodelBuilder.applyTempClassLoader( null );
301+
}
302+
catch (Throwable t) {
303+
bsr.close();
304+
cleanup();
305+
throw t;
306+
}
299307
}
300308

301309
/**
@@ -532,8 +540,9 @@ private MergedSettings mergeSettings(
532540
if ( keyString.startsWith( JACC_PREFIX ) ) {
533541
if( !JACC_CONTEXT_ID.equals( keyString ) && !JACC_ENABLED.equals( keyString )) {
534542
if ( jaccContextId == null ) {
535-
LOG.debug(
536-
"Found JACC permission grant [%s] in properties, but no JACC context id was specified; ignoring"
543+
LOG.debugf(
544+
"Found JACC permission grant [%s] in properties, but no JACC context id was specified; ignoring",
545+
keyString
537546
);
538547
}
539548
else {
@@ -716,7 +725,7 @@ else if ( persistenceUnit.getTransactionType() != null ) {
716725

717726
if ( txnType == null ) {
718727
// is it more appropriate to have this be based on bootstrap entry point (EE vs SE)?
719-
LOG.debugf( "PersistenceUnitTransactionType not specified - falling back to RESOURCE_LOCAL" );
728+
LOG.debug( "PersistenceUnitTransactionType not specified - falling back to RESOURCE_LOCAL" );
720729
txnType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
721730
}
722731

hibernate-core/src/test/java/org/hibernate/cache/internal/CacheKeyImplementationHashCodeTest.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,23 @@ public class CacheKeyImplementationHashCodeTest {
3434
@Test
3535
@TestForIssue( jiraKey = "HHH-12746")
3636
public void test() {
37-
ServiceRegistryImplementor serviceRegistry = (
38-
ServiceRegistryImplementor) new StandardServiceRegistryBuilder().build();
39-
MetadataSources ms = new MetadataSources( serviceRegistry );
40-
ms.addAnnotatedClass( AnEntity.class ).addAnnotatedClass( AnotherEntity.class );
41-
Metadata metadata = ms.buildMetadata();
42-
final SessionFactoryBuilder sfb = metadata.getSessionFactoryBuilder();
43-
SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) sfb.build();
37+
try (ServiceRegistryImplementor serviceRegistry = (
38+
ServiceRegistryImplementor) new StandardServiceRegistryBuilder().build()) {
39+
MetadataSources ms = new MetadataSources( serviceRegistry );
40+
ms.addAnnotatedClass( AnEntity.class ).addAnnotatedClass( AnotherEntity.class );
41+
Metadata metadata = ms.buildMetadata();
42+
final SessionFactoryBuilder sfb = metadata.getSessionFactoryBuilder();
43+
SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) sfb.build();
4444

4545

46-
CacheKeyImplementation anEntityCacheKey = createCacheKeyImplementation(
47-
1, sessionFactory.getMetamodel().entityPersister( AnEntity.class ), sessionFactory
48-
);
49-
CacheKeyImplementation anotherEntityCacheKey = createCacheKeyImplementation(
50-
1, sessionFactory.getMetamodel().entityPersister( AnotherEntity.class ), sessionFactory
51-
);
52-
assertFalse( anEntityCacheKey.equals( anotherEntityCacheKey ) );
46+
CacheKeyImplementation anEntityCacheKey = createCacheKeyImplementation(
47+
1, sessionFactory.getMetamodel().entityPersister( AnEntity.class ), sessionFactory
48+
);
49+
CacheKeyImplementation anotherEntityCacheKey = createCacheKeyImplementation(
50+
1, sessionFactory.getMetamodel().entityPersister( AnotherEntity.class ), sessionFactory
51+
);
52+
assertFalse( anEntityCacheKey.equals( anotherEntityCacheKey ) );
53+
}
5354
}
5455

5556
private CacheKeyImplementation createCacheKeyImplementation(

hibernate-core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
2323
import org.hibernate.service.spi.ServiceRegistryImplementor;
2424
import org.hibernate.testing.junit4.BaseUnitTestCase;
25+
import org.junit.After;
2526
import org.junit.Before;
2627
import org.junit.Test;
2728

@@ -50,6 +51,13 @@ public void setUp() {
5051
dialectFactory.injectServices( (ServiceRegistryImplementor) registry );
5152
}
5253

54+
@After
55+
public void destroy() {
56+
if ( registry != null ) {
57+
registry.close();
58+
}
59+
}
60+
5361
@Test
5462
public void testExplicitShortNameUse() {
5563
final Map<String, String> configValues = new HashMap<String, String>();

0 commit comments

Comments
 (0)