@@ -458,7 +458,6 @@ protected boolean isExistingTransaction(Object transaction) {
458
458
}
459
459
460
460
@ Override
461
- @ SuppressWarnings ("deprecation" )
462
461
protected void doBegin (Object transaction , TransactionDefinition definition ) {
463
462
HibernateTransactionObject txObject = (HibernateTransactionObject ) transaction ;
464
463
@@ -470,7 +469,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
470
469
"on a single DataSource, no matter whether Hibernate or JDBC access." );
471
470
}
472
471
473
- Session session = null ;
472
+ SessionImplementor session = null ;
474
473
475
474
try {
476
475
if (!txObject .hasSessionHolder () || txObject .getSessionHolder ().isSynchronizedWithTransaction ()) {
@@ -487,17 +486,18 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
487
486
txObject .setSession (newSession );
488
487
}
489
488
490
- session = txObject .getSessionHolder ().getSession ();
489
+ session = txObject .getSessionHolder ().getSession (). unwrap ( SessionImplementor . class ) ;
491
490
492
491
boolean holdabilityNeeded = this .allowResultAccessAfterCompletion && !txObject .isNewSession ();
493
492
boolean isolationLevelNeeded = (definition .getIsolationLevel () != TransactionDefinition .ISOLATION_DEFAULT );
494
493
if (holdabilityNeeded || isolationLevelNeeded || definition .isReadOnly ()) {
495
- if (this .prepareConnection && isSameConnectionForEntireSession (session )) {
494
+ if (this .prepareConnection && ConnectionReleaseMode .ON_CLOSE .equals (
495
+ session .getJdbcCoordinator ().getLogicalConnection ().getConnectionHandlingMode ().getReleaseMode ())) {
496
496
// We're allowed to change the transaction settings of the JDBC Connection.
497
497
if (logger .isDebugEnabled ()) {
498
498
logger .debug ("Preparing JDBC Connection of Hibernate Session [" + session + "]" );
499
499
}
500
- Connection con = (( SessionImplementor ) session ) .connection ();
500
+ Connection con = session .connection ();
501
501
Integer previousIsolationLevel = DataSourceUtils .prepareConnectionForTransaction (con , definition );
502
502
txObject .setPreviousIsolationLevel (previousIsolationLevel );
503
503
txObject .setReadOnly (definition .isReadOnly ());
@@ -508,6 +508,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
508
508
con .setHoldability (ResultSet .HOLD_CURSORS_OVER_COMMIT );
509
509
}
510
510
}
511
+ txObject .connectionPrepared ();
511
512
}
512
513
else {
513
514
// Not allowed to change the transaction settings of the JDBC Connection.
@@ -516,7 +517,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
516
517
throw new InvalidIsolationLevelException (
517
518
"HibernateTransactionManager is not allowed to support custom isolation levels: " +
518
519
"make sure that its 'prepareConnection' flag is on (the default) and that the " +
519
- "Hibernate connection release mode is set to 'on_close' (the default for JDBC) ." );
520
+ "Hibernate connection release mode is set to ON_CLOSE ." );
520
521
}
521
522
if (logger .isDebugEnabled ()) {
522
523
logger .debug ("Not preparing JDBC Connection of Hibernate Session [" + session + "]" );
@@ -526,7 +527,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
526
527
527
528
if (definition .isReadOnly () && txObject .isNewSession ()) {
528
529
// Just set to MANUAL in case of a new Session for this transaction.
529
- session .setFlushMode (FlushMode .MANUAL );
530
+ session .setHibernateFlushMode (FlushMode .MANUAL );
530
531
// As of 5.1, we're also setting Hibernate's read-only entity mode by default.
531
532
session .setDefaultReadOnly (true );
532
533
}
@@ -535,7 +536,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
535
536
// We need AUTO or COMMIT for a non-read-only transaction.
536
537
FlushMode flushMode = session .getHibernateFlushMode ();
537
538
if (FlushMode .MANUAL .equals (flushMode )) {
538
- session .setFlushMode (FlushMode .AUTO );
539
+ session .setHibernateFlushMode (FlushMode .AUTO );
539
540
txObject .getSessionHolder ().setPreviousFlushMode (flushMode );
540
541
}
541
542
}
@@ -561,8 +562,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
561
562
562
563
// Register the Hibernate Session's JDBC Connection for the DataSource, if set.
563
564
if (getDataSource () != null ) {
564
- SessionImplementor sessionImpl = (SessionImplementor ) session ;
565
- ConnectionHolder conHolder = new ConnectionHolder (sessionImpl ::connection );
565
+ ConnectionHolder conHolder = new ConnectionHolder (session ::connection );
566
566
if (timeout != TransactionDefinition .TIMEOUT_DEFAULT ) {
567
567
conHolder .setTimeoutInSeconds (timeout );
568
568
}
@@ -704,7 +704,6 @@ protected void doSetRollbackOnly(DefaultTransactionStatus status) {
704
704
}
705
705
706
706
@ Override
707
- @ SuppressWarnings ("deprecation" )
708
707
protected void doCleanupAfterCompletion (Object transaction ) {
709
708
HibernateTransactionObject txObject = (HibernateTransactionObject ) transaction ;
710
709
@@ -718,13 +717,14 @@ protected void doCleanupAfterCompletion(Object transaction) {
718
717
TransactionSynchronizationManager .unbindResource (getDataSource ());
719
718
}
720
719
721
- Session session = txObject .getSessionHolder ().getSession ();
722
- if (this .prepareConnection && isPhysicallyConnected (session )) {
723
- // We're running with connection release mode "on_close": We're able to reset
720
+ SessionImplementor session = txObject .getSessionHolder ().getSession ().unwrap (SessionImplementor .class );
721
+ if (txObject .needsConnectionReset () &&
722
+ session .getJdbcCoordinator ().getLogicalConnection ().isPhysicallyConnected ()) {
723
+ // We're running with connection release mode ON_CLOSE: We're able to reset
724
724
// the isolation level and/or read-only flag of the JDBC Connection here.
725
725
// Else, we need to rely on the connection pool to perform proper cleanup.
726
726
try {
727
- Connection con = (( SessionImplementor ) session ) .connection ();
727
+ Connection con = session .connection ();
728
728
Integer previousHoldability = txObject .getPreviousHoldability ();
729
729
if (previousHoldability != null ) {
730
730
con .setHoldability (previousHoldability );
@@ -751,7 +751,7 @@ protected void doCleanupAfterCompletion(Object transaction) {
751
751
logger .debug ("Not closing pre-bound Hibernate Session [" + session + "] after transaction" );
752
752
}
753
753
if (txObject .getSessionHolder ().getPreviousFlushMode () != null ) {
754
- session .setFlushMode (txObject .getSessionHolder ().getPreviousFlushMode ());
754
+ session .setHibernateFlushMode (txObject .getSessionHolder ().getPreviousFlushMode ());
755
755
}
756
756
if (!this .allowResultAccessAfterCompletion && !this .hibernateManagedSession ) {
757
757
disconnectOnCompletion (session );
@@ -772,41 +772,6 @@ protected void disconnectOnCompletion(Session session) {
772
772
session .disconnect ();
773
773
}
774
774
775
- /**
776
- * Return whether the given Hibernate Session will always hold the same
777
- * JDBC Connection. This is used to check whether the transaction manager
778
- * can safely prepare and clean up the JDBC Connection used for a transaction.
779
- * <p>The default implementation checks the Session's connection release mode
780
- * to be "on_close".
781
- * @param session the Hibernate Session to check
782
- * @see ConnectionReleaseMode#ON_CLOSE
783
- */
784
- @ SuppressWarnings ("deprecation" )
785
- protected boolean isSameConnectionForEntireSession (Session session ) {
786
- if (!(session instanceof SessionImplementor )) {
787
- // The best we can do is to assume we're safe.
788
- return true ;
789
- }
790
- ConnectionReleaseMode releaseMode =
791
- ((SessionImplementor ) session ).getJdbcCoordinator ().getConnectionReleaseMode ();
792
- return ConnectionReleaseMode .ON_CLOSE .equals (releaseMode );
793
- }
794
-
795
- /**
796
- * Determine whether the given Session is (still) physically connected
797
- * to the database, that is, holds an active JDBC Connection internally.
798
- * @param session the Hibernate Session to check
799
- * @see #isSameConnectionForEntireSession(Session)
800
- */
801
- protected boolean isPhysicallyConnected (Session session ) {
802
- if (!(session instanceof SessionImplementor )) {
803
- // The best we can do is to check whether we're logically connected.
804
- return session .isConnected ();
805
- }
806
- return ((SessionImplementor ) session ).getJdbcCoordinator ().getLogicalConnection ().isPhysicallyConnected ();
807
- }
808
-
809
-
810
775
/**
811
776
* Convert the given HibernateException to an appropriate exception
812
777
* from the {@code org.springframework.dao} hierarchy.
@@ -834,6 +799,8 @@ private class HibernateTransactionObject extends JdbcTransactionObjectSupport {
834
799
835
800
private boolean newSession ;
836
801
802
+ private boolean needsConnectionReset ;
803
+
837
804
@ Nullable
838
805
private Integer previousHoldability ;
839
806
@@ -872,6 +839,14 @@ public boolean isNewSession() {
872
839
return this .newSession ;
873
840
}
874
841
842
+ public void connectionPrepared () {
843
+ this .needsConnectionReset = true ;
844
+ }
845
+
846
+ public boolean needsConnectionReset () {
847
+ return this .needsConnectionReset ;
848
+ }
849
+
875
850
public void setPreviousHoldability (@ Nullable Integer previousHoldability ) {
876
851
this .previousHoldability = previousHoldability ;
877
852
}
0 commit comments