From 9f1fde71279afa1ddac1f006cc0eede29d9837c7 Mon Sep 17 00:00:00 2001 From: Vlad Mihalcea Date: Tue, 21 Aug 2018 17:45:58 +0300 Subject: [PATCH] HHH-12915 - Concurrency issue within org.hibernate.internal.SessionFactoryImpl --- .../internal/SessionFactoryImpl.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index 19dcb6c9e7..4cc5f98c03 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -157,7 +157,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { private final String name; private final String uuid; - private transient boolean isClosed; + private transient volatile boolean isClosed; private final transient SessionFactoryObserverChain observer = new SessionFactoryObserverChain(); @@ -166,7 +166,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { private final transient Map properties; private final transient SessionFactoryServiceRegistry serviceRegistry; - private transient JdbcServices jdbcServices; + private final transient JdbcServices jdbcServices; private final transient SQLFunctionRegistry sqlFunctionRegistry; @@ -181,7 +181,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { private final transient CurrentSessionContext currentSessionContext; - private DelayedDropAction delayedDropAction; + private volatile DelayedDropAction delayedDropAction; // todo : move to MetamodelImpl private final transient Map identifierGenerators; @@ -219,7 +219,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { this.name = sfName; this.uuid = options.getUuid(); - final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class ); + jdbcServices = serviceRegistry.getService( JdbcServices.class ); this.properties = new HashMap<>(); this.properties.putAll( serviceRegistry.getService( ConfigurationService.class ).getSettings() ); @@ -544,9 +544,6 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { @Override public JdbcServices getJdbcServices() { - if ( jdbcServices == null ) { - jdbcServices = getServiceRegistry().getService( JdbcServices.class ); - } return jdbcServices; } @@ -780,20 +777,22 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { public void close() throws HibernateException { //This is an idempotent operation so we can do it even before the checks (it won't hurt): Environment.getBytecodeProvider().resetCaches(); - if ( isClosed ) { - if ( getSessionFactoryOptions().getJpaCompliance().isJpaClosedComplianceEnabled() ) { - throw new IllegalStateException( "EntityManagerFactory is already closed" ); + synchronized (this) { + if ( isClosed ) { + if ( getSessionFactoryOptions().getJpaCompliance().isJpaClosedComplianceEnabled() ) { + throw new IllegalStateException( "EntityManagerFactory is already closed" ); + } + + LOG.trace( "Already closed" ); + return; } - LOG.trace( "Already closed" ); - return; + isClosed = true; } LOG.closing(); observer.sessionFactoryClosing( this ); - isClosed = true; - settings.getMultiTableBulkIdStrategy().release( serviceRegistry.getService( JdbcServices.class ), buildLocalConnectionAccess() ); // NOTE : the null checks below handle cases where close is called from