From 44b93038771b314aa64308d5f0f3ac1108314a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Thu, 14 Jan 2021 10:34:51 +0100 Subject: [PATCH] HHH-14326 Release JDBC resources before closing the connection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Yoann Rodière --- .../LogicalConnectionManagedImpl.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/resource/jdbc/internal/LogicalConnectionManagedImpl.java b/hibernate-core/src/main/java/org/hibernate/resource/jdbc/internal/LogicalConnectionManagedImpl.java index b51ad13a91..3584b6d6c3 100644 --- a/hibernate-core/src/main/java/org/hibernate/resource/jdbc/internal/LogicalConnectionManagedImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/resource/jdbc/internal/LogicalConnectionManagedImpl.java @@ -194,16 +194,28 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple } private void releaseConnection() { - //Some managed containers might trigger this release concurrently: - //this is not how they should do things, still we make a local - //copy of the variable to prevent confusing errors due to a race conditions - //(to trigger a more clear error, if any). final Connection localVariableConnection = this.physicalConnection; if ( localVariableConnection == null ) { return; } + // We need to set the connection to null before we release resources, + // in order to prevent recursion into this method. + // Recursion can happen when we release resources and when batch statements are in progress: + // when releasing resources, we'll abort the batch statement, + // which will trigger "logicalConnection.afterStatement()", + // which in some configurations will release the connection. + + //Some managed containers might trigger this release concurrently: + //this is not how they should do things, still we try to detect it to trigger a more clear error. + boolean concurrentUsageDetected = ( this.physicalConnection == null ); + this.physicalConnection = null; + if ( concurrentUsageDetected ) { + throw new HibernateException( "Detected concurrent management of connection resources." + + " This might indicate a multi-threaded use of Hibernate in combination with managed resources, which is not supported." ); + } try { + getResourceRegistry().releaseResources(); if ( ! localVariableConnection.isClosed() ) { sqlExceptionHelper.logAndClearWarnings( localVariableConnection ); } @@ -214,13 +226,6 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple } finally { observer.jdbcConnectionReleaseEnd(); - boolean concurrentUsageDetected = ( this.physicalConnection == null ); - this.physicalConnection = null; - getResourceRegistry().releaseResources(); - if ( concurrentUsageDetected ) { - throw new HibernateException( "Detected concurrent management of connection resources." + - " This might indicate a multi-threaded use of Hibernate in combination with managed resources, which is not supported." ); - } } }