1111import java .sql .SQLException ;
1212
1313import org .hibernate .ResourceClosedException ;
14+ import org .hibernate .engine .jdbc .connections .spi .JdbcConnectionAccess ;
15+ import org .hibernate .engine .jdbc .spi .SqlExceptionHelper ;
1416import org .hibernate .internal .CoreLogging ;
1517import org .hibernate .internal .CoreMessageLogger ;
1618import org .hibernate .resource .jdbc .LogicalConnection ;
1719import org .hibernate .resource .jdbc .ResourceRegistry ;
18- import org .hibernate .resource .jdbc .spi .JdbcEventHandler ;
20+ import org .hibernate .resource .jdbc .spi .JdbcSessionContext ;
1921import org .hibernate .resource .jdbc .spi .JdbcSessionOwner ;
2022import org .hibernate .resource .jdbc .spi .PhysicalConnectionHandlingMode ;
2123
@@ -70,41 +72,41 @@ private LogicalConnectionManagedImpl(JdbcSessionOwner owner, boolean closed) {
7072 this .closed = closed ;
7173 }
7274
73- private Connection acquireConnectionIfNeeded () {
74- if ( physicalConnection == null ) {
75- final JdbcEventHandler eventHandler = jdbcSessionOwner .getJdbcSessionContext ().getEventHandler ();
76- eventHandler .jdbcConnectionAcquisitionStart ();
77- try {
78- physicalConnection = jdbcSessionOwner .getJdbcConnectionAccess ().obtainConnection ();
79- }
80- catch ( SQLException e ) {
81- throw jdbcSessionOwner .getSqlExceptionHelper ()
82- .convert ( e , "Unable to acquire JDBC Connection" );
83- }
84- finally {
85- eventHandler .jdbcConnectionAcquisitionEnd ( physicalConnection );
86- }
75+ private JdbcSessionContext getJdbcSessionContext () {
76+ return jdbcSessionOwner .getJdbcSessionContext ();
77+ }
8778
88- try {
89- jdbcSessionOwner .afterObtainConnection ( physicalConnection );
90- }
91- catch (SQLException e ) {
92- try {
93- // given the session a chance to set the schema
94- jdbcSessionOwner .getJdbcConnectionAccess ().releaseConnection ( physicalConnection );
95- }
96- catch (SQLException re ) {
97- e .addSuppressed ( re );
98- }
99- throw jdbcSessionOwner .getSqlExceptionHelper ()
100- .convert ( e , "Error after acquiring JDBC Connection" );
101- }
79+ private JdbcConnectionAccess getJdbcConnectionAccess () {
80+ return jdbcSessionOwner .getJdbcConnectionAccess ();
81+ }
10282
103- }
83+ private SqlExceptionHelper getExceptionHelper () {
84+ return jdbcSessionOwner .getSqlExceptionHelper ();
85+ }
10486
87+ private Connection acquireConnectionIfNeeded () {
88+ if ( physicalConnection == null ) {
89+ physicalConnection = acquire ();
90+ afterAcquire ();
91+ }
10592 return physicalConnection ;
10693 }
10794
95+ private void releaseConnectionIfNeeded () {
96+ final Connection connection = physicalConnection ;
97+ if ( connection != null ) {
98+ beforeRelease ();
99+ // Set the connection to null before releasing resources to prevent
100+ // recursion into this method. Recursion can happen when we release
101+ // resources and when batch statements are in progress: releasing
102+ // resources aborts the batch statement, which then triggers
103+ // logicalConnection.afterStatement(), which in some configurations
104+ // releases the connection.
105+ physicalConnection = null ;
106+ release ( connection );
107+ }
108+ }
109+
108110 @ Override
109111 public boolean isOpen () {
110112 return !closed ;
@@ -135,7 +137,7 @@ public void afterStatement() {
135137 }
136138 else {
137139 log .debug ( "Initiating JDBC connection release from afterStatement" );
138- releaseConnection ();
140+ releaseConnectionIfNeeded ();
139141 }
140142 }
141143 }
@@ -145,7 +147,7 @@ public void beforeTransactionCompletion() {
145147 super .beforeTransactionCompletion ();
146148 if ( connectionHandlingMode .getReleaseMode () == BEFORE_TRANSACTION_COMPLETION ) {
147149 log .debug ( "Initiating JDBC connection release from beforeTransactionCompletion" );
148- releaseConnection ();
150+ releaseConnectionIfNeeded ();
149151 }
150152 }
151153
@@ -158,7 +160,7 @@ public void afterTransaction() {
158160 // - BEFORE_TRANSACTION_COMPLETION cases that were circumvented because a rollback occurred
159161 // (we don't get a beforeTransactionCompletion event on rollback).
160162 log .debug ( "Initiating JDBC connection release from afterTransaction" );
161- releaseConnection ();
163+ releaseConnectionIfNeeded ();
162164 }
163165 }
164166
@@ -168,7 +170,7 @@ public Connection manualDisconnect() {
168170 throw new ResourceClosedException ( "Logical connection is closed" );
169171 }
170172 final Connection connection = physicalConnection ;
171- releaseConnection ();
173+ releaseConnectionIfNeeded ();
172174 return connection ;
173175 }
174176
@@ -180,44 +182,65 @@ public void manualReconnect(Connection suppliedConnection) {
180182 throw new IllegalStateException ( "Cannot manually reconnect unless Connection was originally supplied by user" );
181183 }
182184
183- private void releaseConnection () {
184- final Connection localVariableConnection = physicalConnection ;
185- if ( localVariableConnection != null ) {
185+ private Connection acquire () {
186+ final var eventHandler = getJdbcSessionContext ().getEventHandler ();
187+ eventHandler .jdbcConnectionAcquisitionStart ();
188+ try {
189+ return getJdbcConnectionAccess ().obtainConnection ();
190+ }
191+ catch ( SQLException e ) {
192+ throw getExceptionHelper ().convert ( e , "Unable to acquire JDBC Connection" );
193+ }
194+ finally {
195+ eventHandler .jdbcConnectionAcquisitionEnd ( physicalConnection );
196+ }
197+ }
198+
199+ private void release (Connection connection ) {
200+ final var eventHandler = getJdbcSessionContext ().getEventHandler ();
201+ try {
186202 try {
187- // give the session a chance to change the schema back to null
188- jdbcSessionOwner .beforeReleaseConnection ( physicalConnection );
203+ getResourceRegistry ().releaseResources ();
204+ if ( !connection .isClosed () ) {
205+ getExceptionHelper ().logAndClearWarnings ( connection );
206+ }
189207 }
190- catch (SQLException e ) {
191- log .warn ( "Error before releasing JDBC connection" , e );
208+ finally {
209+ eventHandler .jdbcConnectionReleaseStart ();
210+ getJdbcConnectionAccess ().releaseConnection ( connection );
192211 }
212+ }
213+ catch (SQLException e ) {
214+ throw getExceptionHelper ().convert ( e , "Unable to release JDBC Connection" );
215+ }
216+ finally {
217+ eventHandler .jdbcConnectionReleaseEnd ();
218+ }
219+ }
193220
194- final JdbcEventHandler eventHandler = jdbcSessionOwner .getJdbcSessionContext ().getEventHandler ();
195- // We need to set the connection to null before we release resources,
196- // in order to prevent recursion into this method.
197- // Recursion can happen when we release resources and when batch statements are in progress:
198- // when releasing resources, we'll abort the batch statement,
199- // which will trigger "logicalConnection.afterStatement()",
200- // which in some configurations will release the connection.
201- physicalConnection = null ;
221+ private void afterAcquire () {
222+ try {
223+ // give the session a chance to set the schema
224+ jdbcSessionOwner .afterObtainConnection ( physicalConnection );
225+ }
226+ catch (SQLException e ) {
202227 try {
203- try {
204- getResourceRegistry ().releaseResources ();
205- if ( !localVariableConnection .isClosed () ) {
206- jdbcSessionOwner .getSqlExceptionHelper ().logAndClearWarnings ( localVariableConnection );
207- }
208- }
209- finally {
210- eventHandler .jdbcConnectionReleaseStart ();
211- jdbcSessionOwner .getJdbcConnectionAccess ().releaseConnection ( localVariableConnection );
212- }
228+ getJdbcConnectionAccess ().releaseConnection ( physicalConnection );
213229 }
214- catch (SQLException e ) {
215- throw jdbcSessionOwner .getSqlExceptionHelper ()
216- .convert ( e , "Unable to release JDBC Connection" );
217- }
218- finally {
219- eventHandler .jdbcConnectionReleaseEnd ();
230+ catch (SQLException re ) {
231+ e .addSuppressed ( re );
220232 }
233+ throw getExceptionHelper ().convert ( e , "Error after acquiring JDBC Connection" );
234+ }
235+ }
236+
237+ private void beforeRelease () {
238+ try {
239+ // give the session a chance to change the schema back to null
240+ jdbcSessionOwner .beforeReleaseConnection ( physicalConnection );
241+ }
242+ catch (SQLException e ) {
243+ log .warn ( "Error before releasing JDBC connection" , e );
221244 }
222245 }
223246
@@ -237,7 +260,7 @@ public Connection close() {
237260 getResourceRegistry ().releaseResources ();
238261 log .closingLogicalConnection ();
239262 try {
240- releaseConnection ();
263+ releaseConnectionIfNeeded ();
241264 }
242265 finally {
243266 // no matter what
@@ -260,8 +283,9 @@ protected Connection getConnectionForTransactionManagement() {
260283
261284 @ Override
262285 public void begin () {
263- initiallyAutoCommit = !doConnectionsFromProviderHaveAutoCommitDisabled ()
264- && determineInitialAutoCommitMode ( getConnectionForTransactionManagement () );
286+ initiallyAutoCommit =
287+ !doConnectionsFromProviderHaveAutoCommitDisabled ()
288+ && determineInitialAutoCommitMode ( getConnectionForTransactionManagement () );
265289 super .begin ();
266290 }
267291
@@ -274,6 +298,6 @@ protected void afterCompletion() {
274298
275299 @ Override
276300 protected boolean doConnectionsFromProviderHaveAutoCommitDisabled () {
277- return jdbcSessionOwner . getJdbcSessionContext ().doesConnectionProviderDisableAutoCommit ();
301+ return getJdbcSessionContext ().doesConnectionProviderDisableAutoCommit ();
278302 }
279303}
0 commit comments