Skip to content

Commit eafe6fd

Browse files
committed
HHH-16637 add methods to SessionFactory for handling lifecycle of StatelessSession
also clean up the related code
1 parent e4b31c1 commit eafe6fd

File tree

3 files changed

+128
-65
lines changed

3 files changed

+128
-65
lines changed

hibernate-core/src/main/java/org/hibernate/SessionFactory.java

Lines changed: 39 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import jakarta.persistence.EntityGraph;
2525
import jakarta.persistence.EntityManagerFactory;
2626

27+
import static org.hibernate.internal.TransactionManagement.manageTransaction;
28+
2729
/**
2830
* A {@code SessionFactory} represents an "instance" of Hibernate: it maintains
2931
* the runtime metamodel representing persistent entities, their attributes,
@@ -193,7 +195,16 @@ public interface SessionFactory extends EntityManagerFactory, Referenceable, Ser
193195
* Open a {@link Session} and use it to perform an action.
194196
*/
195197
default void inSession(Consumer<Session> action) {
196-
try (Session session = openSession()) {
198+
try ( Session session = openSession() ) {
199+
action.accept( session );
200+
}
201+
}
202+
203+
/**
204+
* Open a {@link StatelessSession} and use it to perform an action.
205+
*/
206+
default void inStatelessSession(Consumer<StatelessSession> action) {
207+
try ( StatelessSession session = openStatelessSession() ) {
197208
action.accept( session );
198209
}
199210
}
@@ -203,86 +214,49 @@ default void inSession(Consumer<Session> action) {
203214
* within the bounds of a transaction.
204215
*/
205216
default void inTransaction(Consumer<Session> action) {
206-
inSession(
207-
session -> {
208-
final Transaction transaction = session.beginTransaction();
209-
try {
210-
action.accept( session );
211-
if ( !transaction.isActive() ) {
212-
throw new TransactionManagementException(
213-
"Execution of action caused managed transaction to be completed" );
214-
}
215-
}
216-
catch (RuntimeException exception) {
217-
// an error happened in the action
218-
if ( transaction.isActive() ) {
219-
try {
220-
transaction.rollback();
221-
}
222-
catch (Exception ignore) {
223-
}
224-
}
225-
226-
throw exception;
227-
}
228-
// The action completed without throwing an exception,
229-
// so we attempt to commit the transaction, allowing
230-
// any RollbackException to propagate. Note that when
231-
// we get here we know that the transaction is active
232-
transaction.commit();
233-
}
234-
);
217+
inSession( session -> manageTransaction( session, session.beginTransaction(), action ) );
235218
}
236219

237-
class TransactionManagementException extends RuntimeException {
238-
TransactionManagementException(String message) {
239-
super( message );
240-
}
220+
/**
221+
* Open a {@link StatelessSession} and use it to perform an action
222+
* within the bounds of a transaction.
223+
*/
224+
default void inStatelessTransaction(Consumer<StatelessSession> action) {
225+
inStatelessSession( session -> manageTransaction( session, session.beginTransaction(), action ) );
241226
}
242227

243228
/**
244229
* Open a {@link Session} and use it to obtain a value.
245230
*/
246231
default <R> R fromSession(Function<Session,R> action) {
247-
try (Session session = openSession()) {
232+
try ( Session session = openSession() ) {
248233
return action.apply( session );
249234
}
250235
}
251236

252237
/**
253-
* Open a {@link Session} and use it to perform an action
238+
* Open a {@link StatelessSession} and use it to obtain a value.
239+
*/
240+
default <R> R fromStatelessSession(Function<StatelessSession,R> action) {
241+
try ( StatelessSession session = openStatelessSession() ) {
242+
return action.apply( session );
243+
}
244+
}
245+
246+
/**
247+
* Open a {@link Session} and use it to obtain a value
254248
* within the bounds of a transaction.
255249
*/
256250
default <R> R fromTransaction(Function<Session,R> action) {
257-
return fromSession(
258-
session -> {
259-
final Transaction transaction = session.beginTransaction();
260-
try {
261-
R result = action.apply( session );
262-
if ( !transaction.isActive() ) {
263-
throw new TransactionManagementException(
264-
"Execution of action caused managed transaction to be completed" );
265-
}
266-
// The action completed without throwing an exception,
267-
// so we attempt to commit the transaction, allowing
268-
// any RollbackException to propagate. Note that when
269-
// we get here we know that the transaction is active
270-
transaction.commit();
271-
return result;
272-
}
273-
catch (RuntimeException exception) {
274-
// an error happened in the action or during commit()
275-
if ( transaction.isActive() ) {
276-
try {
277-
transaction.rollback();
278-
}
279-
catch (Exception ignore) {
280-
}
281-
}
282-
throw exception;
283-
}
284-
}
285-
);
251+
return fromSession( session -> manageTransaction( session, session.beginTransaction(), action ) );
252+
}
253+
254+
/**
255+
* Open a {@link StatelessSession} and use it to obtain a value
256+
* within the bounds of a transaction.
257+
*/
258+
default <R> R fromStatelessTransaction(Function<StatelessSession,R> action) {
259+
return fromStatelessSession( session -> manageTransaction( session, session.beginTransaction(), action ) );
286260
}
287261

288262
/**
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate;
8+
9+
/**
10+
* Thrown when user code causes the end of a transaction that is
11+
* being managed by the {@link SessionFactory}.
12+
*
13+
* @see SessionFactory#inTransaction
14+
* @see SessionFactory#fromTransaction
15+
*/
16+
public class TransactionManagementException extends RuntimeException {
17+
public TransactionManagementException(String message) {
18+
super( message );
19+
}
20+
}
21+
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.internal;
8+
9+
import org.hibernate.Transaction;
10+
import org.hibernate.TransactionManagementException;
11+
12+
import java.util.function.Consumer;
13+
import java.util.function.Function;
14+
15+
/**
16+
* Methods used by {@link org.hibernate.SessionFactory} to manage transactions.
17+
*/
18+
public class TransactionManagement {
19+
20+
public static <S> void manageTransaction(S session, Transaction transaction, Consumer<S> consumer) {
21+
try {
22+
consumer.accept( session );
23+
commit( transaction );
24+
}
25+
catch ( RuntimeException exception ) {
26+
rollback( transaction, exception );
27+
throw exception;
28+
}
29+
}
30+
31+
public static <S,R> R manageTransaction(S session, Transaction transaction, Function<S,R> function) {
32+
try {
33+
R result = function.apply( session );
34+
commit( transaction );
35+
return result;
36+
}
37+
catch ( RuntimeException exception ) {
38+
// an error happened in the action or during commit()
39+
rollback( transaction, exception );
40+
throw exception;
41+
}
42+
}
43+
44+
private static void rollback(Transaction transaction, RuntimeException exception) {
45+
// an error happened in the action or during commit()
46+
if ( transaction.isActive() ) {
47+
try {
48+
transaction.rollback();
49+
}
50+
catch ( RuntimeException e ) {
51+
exception.addSuppressed( e );
52+
}
53+
}
54+
}
55+
56+
private static void commit(Transaction transaction) {
57+
if ( !transaction.isActive() ) {
58+
throw new TransactionManagementException(
59+
"Execution of action caused managed transaction to be completed" );
60+
}
61+
// The action completed without throwing an exception,
62+
// so we attempt to commit the transaction, allowing
63+
// any RollbackException to propagate. Note that when
64+
// we get here we know that the transaction is active
65+
transaction.commit();
66+
}
67+
68+
}

0 commit comments

Comments
 (0)