diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index 1b38399df7..c71cf3b514 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -1277,7 +1277,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont return new QuerySqmImpl<>( selectStatement, criteriaQuery.getResultType(), this ); } - catch ( RuntimeException e ) { + catch (RuntimeException e) { + if ( getSessionFactory().getJpaMetamodel().getJpaCompliance().isJpaTransactionComplianceEnabled() ) { + markForRollbackOnly(); + } throw getExceptionConverter().convert( e ); } } @@ -1292,7 +1295,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont this ); } - catch ( RuntimeException e ) { + catch (RuntimeException e) { + if ( getSessionFactory().getJpaMetamodel().getJpaCompliance().isJpaTransactionComplianceEnabled() ) { + markForRollbackOnly(); + } throw getExceptionConverter().convert( e ); } } @@ -1307,7 +1313,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont this ); } - catch ( RuntimeException e ) { + catch (RuntimeException e) { + if ( getSessionFactory().getJpaMetamodel().getJpaCompliance().isJpaTransactionComplianceEnabled() ) { + markForRollbackOnly(); + } throw getExceptionConverter().convert( e ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/compliance/EntityManagerCreateQueryRuntimeExceptionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/compliance/EntityManagerCreateQueryRuntimeExceptionTest.java new file mode 100644 index 0000000000..c7507b72da --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/compliance/EntityManagerCreateQueryRuntimeExceptionTest.java @@ -0,0 +1,119 @@ +/* + * 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.orm.test.jpa.compliance; + +import org.hibernate.cfg.AvailableSettings; + +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.criteria.CriteriaDelete; +import jakarta.persistence.criteria.CriteriaQuery; + +import static org.junit.jupiter.api.Assertions.fail; + +@Jpa( + properties = @Setting( name = AvailableSettings.JPA_TRANSACTION_COMPLIANCE, value = "true") +) +public class EntityManagerCreateQueryRuntimeExceptionTest { + + @Test + public void testCriteriaDelete(EntityManagerFactoryScope scope) { + scope.inEntityManager( + entityManager -> { + try { + entityManager.getTransaction().begin(); + + final CriteriaDelete deleteQuery = entityManager.getCriteriaBuilder() + .createCriteriaDelete( NonEntityClass.class ); + deleteQuery.from( NonEntityClass.class ); + try { + entityManager.createQuery( deleteQuery ).executeUpdate(); + fail( "Runtime Exception expected" ); + } + catch (RuntimeException e) { + // expected + if ( !entityManager.getTransaction().getRollbackOnly() ) { + fail( "Transaction was not marked for ", e ); + } + } + } + catch (RuntimeException e) { + // expected + } + finally { + if ( entityManager.getTransaction().isActive() ) { + entityManager.getTransaction().rollback(); + } + } + } ); + } + + @Test + public void testCriteriaQuery(EntityManagerFactoryScope scope) { + scope.inEntityManager( + entityManager -> { + try { + entityManager.getTransaction().begin(); + + CriteriaQuery query = entityManager.getCriteriaBuilder() + .createQuery( NonEntityClass.class ); + + entityManager.createQuery( query ).executeUpdate(); + entityManager.getTransaction().commit(); + fail( "RuntimeException expected" ); + } + catch (RuntimeException e) { + //expected + if ( !entityManager.getTransaction().getRollbackOnly() ) { + fail( "Transaction was not marked for rollback", e ); + } + } + finally { + if ( entityManager.getTransaction().isActive() ) { + entityManager.getTransaction().rollback(); + } + } + } + ); + } + + @Test + public void testHqlQuery(EntityManagerFactoryScope scope) { + scope.inEntityManager( + entityManager -> { + try { + entityManager.getTransaction().begin(); + + entityManager.createQuery( "select" ).executeUpdate(); + + entityManager.getTransaction().commit(); + fail( "RuntimeException expected" ); + } + catch (RuntimeException e) { + //expected + if ( !entityManager.getTransaction().getRollbackOnly() ) { + fail( "Transaction was not marked for rollback", e ); + } + } + finally { + if ( entityManager.getTransaction().isActive() ) { + entityManager.getTransaction().rollback(); + } + } + } + ); + + + } + + public class NonEntityClass { + } + +}