fix tests which were asserting stuff about JPA compliance for a non-JPA method

The JPA spec does not have anything to say about our beginTransaction() method
This commit is contained in:
Gavin King 2024-11-20 23:26:00 +01:00
parent 945ec124fc
commit 597f74f23e
5 changed files with 45 additions and 12 deletions

View File

@ -68,17 +68,29 @@ public interface SharedSessionContract extends QueryProducer, AutoCloseable, Ser
* Begin a unit of work and return the associated {@link Transaction} object.
* If a new underlying transaction is required, begin the transaction. Otherwise,
* continue the new work in the context of the existing underlying transaction.
* <p>
* The JPA-standard way to begin a new transaction is by calling
* {@link #getTransaction getTransaction().begin()}. When
*
* @apiNote
* The JPA-standard way to begin a new resource-local transaction is by calling
* {@link #getTransaction getTransaction().begin()}. But it's not always safe to
* execute this idiom.
* <ul>
* <li>JPA doesn't allow an {@link jakarta.persistence.EntityTransaction
* EntityTransaction} to represent a JTA transaction context. Therefore, when
* {@linkplain org.hibernate.jpa.spi.JpaCompliance#isJpaTransactionComplianceEnabled
* strict JPA transaction compliance} is enabled via, for example, setting
* {@value org.hibernate.cfg.JpaComplianceSettings#JPA_TRANSACTION_COMPLIANCE},
* or when resource-local transactions are used, the call to {@code begin()}
* fails if the transaction is already {@linkplain Transaction#isActive active}.
* On the other hand, this method does not fail when a transaction is already
* active, and simply returns the {@link Transaction} object representing the
* active transaction.
* the call to {@code getTransaction()} fails if transactions are managed by JTA.
* <p>
* On the other hand, this method does not fail when JTA transaction management
* is used, not even if strict JPA transaction compliance is enabled.
* <li>Even when resource-local transactions are in use, and even when strict JPA
* transaction compliance is <em>disabled</em>, the call to {@code begin()}
* fails if a transaction is already {@linkplain Transaction#isActive active}.
* <p>
* This method never fails when a transaction is already active. Instead,
* {@code beginTransaction()} simply returns the {@link Transaction} object
* representing the active transaction.
* </ul>
*
* @return an instance of {@link Transaction} representing the new transaction
*
@ -90,6 +102,20 @@ public interface SharedSessionContract extends QueryProducer, AutoCloseable, Ser
/**
* Get the {@link Transaction} instance associated with this session.
*
* @apiNote
* This method is the JPA-standard way to obtain an instance of
* {@link jakarta.persistence.EntityTransaction EntityTransaction}
* representing a resource-local transaction. But JPA doesn't allow an
* {@code EntityTransaction} to represent a JTA transaction. Therefore, when
* {@linkplain org.hibernate.jpa.spi.JpaCompliance#isJpaTransactionComplianceEnabled
* strict JPA transaction compliance} is enabled via, for example, setting
* {@value org.hibernate.cfg.JpaComplianceSettings#JPA_TRANSACTION_COMPLIANCE},
* this method fails if transactions are managed by JTA.
* <p>
* On the other hand, when JTA transaction management is used, and when
* strict JPA transaction compliance is <em>disabled</em>, this method happily
* returns a {@link Transaction} representing the current JTA transaction context.
*
* @return an instance of {@link Transaction} representing the transaction
* associated with this session
*

View File

@ -17,7 +17,7 @@ import org.hibernate.resource.transaction.spi.TransactionStatus;
* depending on how Hibernate is configured.
* <p>
* Every resource-local transaction is associated with a {@link Session} and begins with
* an explicit call to {@link Session#beginTransaction()}, or, equivalently, with
* an explicit call to {@link Session#beginTransaction()}, or, almost equivalently, with
* {@code session.getTransaction().begin()}, and ends with a call to {@link #commit()}
* or {@link #rollback()}.
* <p>
@ -31,6 +31,11 @@ import org.hibernate.resource.transaction.spi.TransactionStatus;
* <p>
* A {@code Transaction} object is not threadsafe.
*
* @apiNote JPA doesn't allow an {@link EntityTransaction} to represent a JTA transaction.
* But when {@linkplain org.hibernate.jpa.spi.JpaCompliance#isJpaTransactionComplianceEnabled
* strict JPA transaction compliance} is disabled, as it is by default, Hibernate allows an
* instance of this interface to represent the current JTA transaction context.
*
* @author Anton van Straaten
* @author Steve Ebersole
*

View File

@ -610,7 +610,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
@Override
public Transaction beginTransaction() {
checkOpen();
final Transaction transaction = getTransaction();
final Transaction transaction = accessTransaction();
// only need to begin a transaction if it was not
// already active (this is the documented semantics)
if ( !transaction.isActive() ) {

View File

@ -45,7 +45,8 @@ public class JpaComplianceAlreadyStartedTransactionTest extends BaseNonConfigCor
Transaction tx = null;
try {
// A call to begin() with an active Tx should cause an IllegalStateException
tx = s.beginTransaction();
tx = s.getTransaction();
tx.begin();
}
catch (Exception e) {
if ( tx != null && tx.isActive() ) {

View File

@ -50,7 +50,8 @@ public class NonJpaComplianceAlreadyStartedTransactionTest extends BaseNonConfig
public void noIllegalStateExceptionShouldBeThrownWhenBeginTxIsCalledWithAnAlreadyActiveTx() throws Exception {
tm.begin();
try (Session s = openSession()) {
Transaction tx = s.beginTransaction();
Transaction tx = s.getTransaction();
tx.begin();
try {
s.persist( new TestEntity( "ABC" ) );
tx.commit();