|
9 | 9 | import jakarta.transaction.Synchronization; |
10 | 10 | import jakarta.transaction.Transaction; |
11 | 11 |
|
| 12 | +import jakarta.transaction.TransactionManager; |
| 13 | +import org.checkerframework.checker.nullness.qual.NonNull; |
12 | 14 | import org.hibernate.FlushMode; |
13 | 15 | import org.hibernate.HibernateException; |
14 | 16 | import org.hibernate.Session; |
@@ -62,53 +64,57 @@ public Session currentSession() throws HibernateException { |
62 | 64 | throw new HibernateException( "No TransactionManagerLookup specified" ); |
63 | 65 | } |
64 | 66 |
|
65 | | -Transaction txn; |
| 67 | +final var txn = getTransaction( transactionManager ); |
| 68 | +final Object txnIdentifier = jtaPlatform.getTransactionIdentifier( txn ); |
| 69 | + |
| 70 | +Session currentSession = currentSessionMap.get( txnIdentifier ); |
| 71 | +if ( currentSession == null ) { |
| 72 | +currentSession = buildOrObtainSession(); |
| 73 | +registerSynchronization( txn, txnIdentifier, currentSession ); |
| 74 | +currentSessionMap.put( txnIdentifier, currentSession ); |
| 75 | +} |
| 76 | +else { |
| 77 | +validateExistingSession( currentSession ); |
| 78 | +} |
| 79 | + |
| 80 | +return currentSession; |
| 81 | +} |
| 82 | + |
| 83 | +private void registerSynchronization(Transaction txn, Object txnIdentifier, Session currentSession) { |
| 84 | +try { |
| 85 | +txn.registerSynchronization( buildCleanupSynch( txnIdentifier ) ); |
| 86 | +} |
| 87 | +catch ( Throwable t ) { |
| 88 | +try { |
| 89 | +currentSession.close(); |
| 90 | +} |
| 91 | +catch ( Throwable e ) { |
| 92 | +CURRENT_SESSION_LOGGER.unableToReleaseGeneratedCurrentSessionOnFailedSynchronizationRegistration(e); |
| 93 | +} |
| 94 | +throw new HibernateException( "Unable to register cleanup Synchronization with TransactionManager" ); |
| 95 | +} |
| 96 | +} |
| 97 | + |
| 98 | +private static @NonNull Transaction getTransaction(TransactionManager transactionManager) { |
66 | 99 | try { |
67 | | -txn = transactionManager.getTransaction(); |
68 | | -if ( txn == null ) { |
| 100 | +final var transaction = transactionManager.getTransaction(); |
| 101 | +if ( transaction == null ) { |
69 | 102 | throw new HibernateException( "Unable to locate current JTA transaction" ); |
70 | 103 | } |
71 | | -if ( !isActive( txn.getStatus() ) ) { |
| 104 | +if ( !isActive( transaction.getStatus() ) ) { |
72 | 105 | // We could register the session against the transaction even though it is |
73 | 106 | // not started, but we'd have no guarantee of ever getting the map |
74 | 107 | // entries cleaned up (aside from spawning threads). |
75 | 108 | throw new HibernateException( "Current transaction is not in progress" ); |
76 | 109 | } |
| 110 | +return transaction; |
77 | 111 | } |
78 | 112 | catch ( HibernateException e ) { |
79 | 113 | throw e; |
80 | 114 | } |
81 | 115 | catch ( Throwable t ) { |
82 | 116 | throw new HibernateException( "Problem locating/validating JTA transaction", t ); |
83 | 117 | } |
84 | | - |
85 | | -final Object txnIdentifier = jtaPlatform.getTransactionIdentifier( txn ); |
86 | | - |
87 | | -Session currentSession = currentSessionMap.get( txnIdentifier ); |
88 | | - |
89 | | -if ( currentSession == null ) { |
90 | | -currentSession = buildOrObtainSession(); |
91 | | - |
92 | | -try { |
93 | | -txn.registerSynchronization( buildCleanupSynch( txnIdentifier ) ); |
94 | | -} |
95 | | -catch ( Throwable t ) { |
96 | | -try { |
97 | | -currentSession.close(); |
98 | | -} |
99 | | -catch ( Throwable e ) { |
100 | | -CURRENT_SESSION_LOGGER.unableToReleaseGeneratedCurrentSessionOnFailedSynchronizationRegistration(e); |
101 | | -} |
102 | | -throw new HibernateException( "Unable to register cleanup Synchronization with TransactionManager" ); |
103 | | -} |
104 | | - |
105 | | -currentSessionMap.put( txnIdentifier, currentSession ); |
106 | | -} |
107 | | -else { |
108 | | -validateExistingSession( currentSession ); |
109 | | -} |
110 | | - |
111 | | -return currentSession; |
112 | 118 | } |
113 | 119 |
|
114 | 120 | /** |
|
0 commit comments