HHH-16637 add methods to SessionFactory for handling lifecycle of StatelessSession
also clean up the related code
This commit is contained in:
parent
e4b31c192e
commit
eafe6fd79b
|
@ -24,6 +24,8 @@ import org.hibernate.stat.Statistics;
|
|||
import jakarta.persistence.EntityGraph;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
|
||||
import static org.hibernate.internal.TransactionManagement.manageTransaction;
|
||||
|
||||
/**
|
||||
* A {@code SessionFactory} represents an "instance" of Hibernate: it maintains
|
||||
* the runtime metamodel representing persistent entities, their attributes,
|
||||
|
@ -193,7 +195,16 @@ public interface SessionFactory extends EntityManagerFactory, Referenceable, Ser
|
|||
* Open a {@link Session} and use it to perform an action.
|
||||
*/
|
||||
default void inSession(Consumer<Session> action) {
|
||||
try (Session session = openSession()) {
|
||||
try ( Session session = openSession() ) {
|
||||
action.accept( session );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a {@link StatelessSession} and use it to perform an action.
|
||||
*/
|
||||
default void inStatelessSession(Consumer<StatelessSession> action) {
|
||||
try ( StatelessSession session = openStatelessSession() ) {
|
||||
action.accept( session );
|
||||
}
|
||||
}
|
||||
|
@ -203,86 +214,49 @@ public interface SessionFactory extends EntityManagerFactory, Referenceable, Ser
|
|||
* within the bounds of a transaction.
|
||||
*/
|
||||
default void inTransaction(Consumer<Session> action) {
|
||||
inSession(
|
||||
session -> {
|
||||
final Transaction transaction = session.beginTransaction();
|
||||
try {
|
||||
action.accept( session );
|
||||
if ( !transaction.isActive() ) {
|
||||
throw new TransactionManagementException(
|
||||
"Execution of action caused managed transaction to be completed" );
|
||||
}
|
||||
}
|
||||
catch (RuntimeException exception) {
|
||||
// an error happened in the action
|
||||
if ( transaction.isActive() ) {
|
||||
try {
|
||||
transaction.rollback();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
throw exception;
|
||||
}
|
||||
// The action completed without throwing an exception,
|
||||
// so we attempt to commit the transaction, allowing
|
||||
// any RollbackException to propagate. Note that when
|
||||
// we get here we know that the transaction is active
|
||||
transaction.commit();
|
||||
}
|
||||
);
|
||||
inSession( session -> manageTransaction( session, session.beginTransaction(), action ) );
|
||||
}
|
||||
|
||||
class TransactionManagementException extends RuntimeException {
|
||||
TransactionManagementException(String message) {
|
||||
super( message );
|
||||
}
|
||||
/**
|
||||
* Open a {@link StatelessSession} and use it to perform an action
|
||||
* within the bounds of a transaction.
|
||||
*/
|
||||
default void inStatelessTransaction(Consumer<StatelessSession> action) {
|
||||
inStatelessSession( session -> manageTransaction( session, session.beginTransaction(), action ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a {@link Session} and use it to obtain a value.
|
||||
*/
|
||||
default <R> R fromSession(Function<Session,R> action) {
|
||||
try (Session session = openSession()) {
|
||||
try ( Session session = openSession() ) {
|
||||
return action.apply( session );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a {@link Session} and use it to perform an action
|
||||
* Open a {@link StatelessSession} and use it to obtain a value.
|
||||
*/
|
||||
default <R> R fromStatelessSession(Function<StatelessSession,R> action) {
|
||||
try ( StatelessSession session = openStatelessSession() ) {
|
||||
return action.apply( session );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a {@link Session} and use it to obtain a value
|
||||
* within the bounds of a transaction.
|
||||
*/
|
||||
default <R> R fromTransaction(Function<Session,R> action) {
|
||||
return fromSession(
|
||||
session -> {
|
||||
final Transaction transaction = session.beginTransaction();
|
||||
try {
|
||||
R result = action.apply( session );
|
||||
if ( !transaction.isActive() ) {
|
||||
throw new TransactionManagementException(
|
||||
"Execution of action caused managed transaction to be completed" );
|
||||
}
|
||||
// The action completed without throwing an exception,
|
||||
// so we attempt to commit the transaction, allowing
|
||||
// any RollbackException to propagate. Note that when
|
||||
// we get here we know that the transaction is active
|
||||
transaction.commit();
|
||||
return result;
|
||||
}
|
||||
catch (RuntimeException exception) {
|
||||
// an error happened in the action or during commit()
|
||||
if ( transaction.isActive() ) {
|
||||
try {
|
||||
transaction.rollback();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
);
|
||||
return fromSession( session -> manageTransaction( session, session.beginTransaction(), action ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a {@link StatelessSession} and use it to obtain a value
|
||||
* within the bounds of a transaction.
|
||||
*/
|
||||
default <R> R fromStatelessTransaction(Function<StatelessSession,R> action) {
|
||||
return fromStatelessSession( session -> manageTransaction( session, session.beginTransaction(), action ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate;
|
||||
|
||||
/**
|
||||
* Thrown when user code causes the end of a transaction that is
|
||||
* being managed by the {@link SessionFactory}.
|
||||
*
|
||||
* @see SessionFactory#inTransaction
|
||||
* @see SessionFactory#fromTransaction
|
||||
*/
|
||||
public class TransactionManagementException extends RuntimeException {
|
||||
public TransactionManagementException(String message) {
|
||||
super( message );
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.internal;
|
||||
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransactionManagementException;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Methods used by {@link org.hibernate.SessionFactory} to manage transactions.
|
||||
*/
|
||||
public class TransactionManagement {
|
||||
|
||||
public static <S> void manageTransaction(S session, Transaction transaction, Consumer<S> consumer) {
|
||||
try {
|
||||
consumer.accept( session );
|
||||
commit( transaction );
|
||||
}
|
||||
catch ( RuntimeException exception ) {
|
||||
rollback( transaction, exception );
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
public static <S,R> R manageTransaction(S session, Transaction transaction, Function<S,R> function) {
|
||||
try {
|
||||
R result = function.apply( session );
|
||||
commit( transaction );
|
||||
return result;
|
||||
}
|
||||
catch ( RuntimeException exception ) {
|
||||
// an error happened in the action or during commit()
|
||||
rollback( transaction, exception );
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
private static void rollback(Transaction transaction, RuntimeException exception) {
|
||||
// an error happened in the action or during commit()
|
||||
if ( transaction.isActive() ) {
|
||||
try {
|
||||
transaction.rollback();
|
||||
}
|
||||
catch ( RuntimeException e ) {
|
||||
exception.addSuppressed( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void commit(Transaction transaction) {
|
||||
if ( !transaction.isActive() ) {
|
||||
throw new TransactionManagementException(
|
||||
"Execution of action caused managed transaction to be completed" );
|
||||
}
|
||||
// The action completed without throwing an exception,
|
||||
// so we attempt to commit the transaction, allowing
|
||||
// any RollbackException to propagate. Note that when
|
||||
// we get here we know that the transaction is active
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue