From 5fd8b36e3411f8d97a6d4de8502a2c5c818572df Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Thu, 19 Jul 2018 23:13:29 -0700 Subject: [PATCH] HHH-12666 : Add test --- .../ExceptionExpectations.java | 58 +++++ .../TransactionExceptionHandlingTest.java | 213 ++++++++++++++++++ 2 files changed, 271 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/exceptionhandling/TransactionExceptionHandlingTest.java diff --git a/hibernate-core/src/test/java/org/hibernate/test/exceptionhandling/ExceptionExpectations.java b/hibernate-core/src/test/java/org/hibernate/test/exceptionhandling/ExceptionExpectations.java index 8e5f239826..26daa5688e 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/exceptionhandling/ExceptionExpectations.java +++ b/hibernate-core/src/test/java/org/hibernate/test/exceptionhandling/ExceptionExpectations.java @@ -9,8 +9,10 @@ package org.hibernate.test.exceptionhandling; import java.sql.SQLException; import javax.persistence.OptimisticLockException; import javax.persistence.PersistenceException; +import javax.persistence.RollbackException; import org.hibernate.StaleObjectStateException; +import org.hibernate.TransactionException; import org.hibernate.TransientObjectException; import org.hibernate.exception.ConstraintViolationException; import org.hibernate.hql.internal.ast.QuerySyntaxException; @@ -63,6 +65,24 @@ interface ExceptionExpectations { assertThat( e, instanceOf( PersistenceException.class ) ); assertThat( e.getCause(), instanceOf( IdentifierGenerationException.class ) ); } + + @Override + public void onTransactionExceptionOnSaveAndSaveOrUpdate(RuntimeException e) { + assertThat( e, instanceOf( TransactionException.class ) ); + } + + @Override + public void onTransactionExceptionOnPersistAndMergeAndFlush(RuntimeException e) { + assertThat( e, instanceOf( PersistenceException.class ) ); + assertThat( e.getCause(), instanceOf( TransactionException.class ) ); + } + + @Override + public void onTransactionExceptionOnCommit(RuntimeException e) { + assertThat( e, instanceOf( RollbackException.class ) ); + assertThat( e.getCause(), instanceOf( PersistenceException.class ) ); + assertThat( e.getCause().getCause(), instanceOf( TransactionException.class ) ); + } }; } @@ -104,6 +124,21 @@ interface ExceptionExpectations { public void onIdentifierGeneratorFailure(RuntimeException e) { assertThat( e, instanceOf( IdentifierGenerationException.class ) ); } + + @Override + public void onTransactionExceptionOnSaveAndSaveOrUpdate(RuntimeException e) { + assertThat( e, instanceOf( TransactionException.class ) ); + } + + @Override + public void onTransactionExceptionOnPersistAndMergeAndFlush(RuntimeException e) { + assertThat( e, instanceOf( TransactionException.class ) ); + } + + @Override + public void onTransactionExceptionOnCommit(RuntimeException e) { + assertThat( e, instanceOf( TransactionException.class ) ); + } }; } @@ -150,6 +185,23 @@ interface ExceptionExpectations { assertThat( e, instanceOf( PersistenceException.class ) ); assertThat( e.getCause(), instanceOf( IdentifierGenerationException.class ) ); } + + @Override + public void onTransactionExceptionOnSaveAndSaveOrUpdate(RuntimeException e) { + assertThat( e, instanceOf( TransactionException.class ) ); + } + + @Override + public void onTransactionExceptionOnPersistAndMergeAndFlush(RuntimeException e) { + assertThat( e, instanceOf( PersistenceException.class ) ); + assertThat( e.getCause(), instanceOf( TransactionException.class ) ); + } + + @Override + public void onTransactionExceptionOnCommit(RuntimeException e) { + assertThat( e, instanceOf( PersistenceException.class ) ); + assertThat( e.getCause(), instanceOf( TransactionException.class ) ); + } }; } @@ -166,4 +218,10 @@ interface ExceptionExpectations { void onStaleObjectMergeAndUpdateFlush(RuntimeException e); void onIdentifierGeneratorFailure(RuntimeException e); + + void onTransactionExceptionOnSaveAndSaveOrUpdate(RuntimeException e); + + void onTransactionExceptionOnPersistAndMergeAndFlush(RuntimeException e); + + void onTransactionExceptionOnCommit(RuntimeException e); } \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/exceptionhandling/TransactionExceptionHandlingTest.java b/hibernate-core/src/test/java/org/hibernate/test/exceptionhandling/TransactionExceptionHandlingTest.java new file mode 100644 index 0000000000..0abf30053e --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/exceptionhandling/TransactionExceptionHandlingTest.java @@ -0,0 +1,213 @@ +/* + * 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 . + */ +package org.hibernate.test.exceptionhandling; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.engine.spi.SessionImplementor; + +import org.hibernate.testing.TestForIssue; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +@TestForIssue(jiraKey = "HHH-12666") +public class TransactionExceptionHandlingTest extends BaseExceptionHandlingTest { + + public TransactionExceptionHandlingTest( + BootstrapMethod bootstrapMethod, + ExceptionHandlingSetting exceptionHandlingSetting, + ExceptionExpectations exceptionExpectations) { + super( bootstrapMethod, exceptionHandlingSetting, exceptionExpectations ); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + A.class, + B.class + }; + } + + @Test + public void testPersistWithGeneratedValue() throws Exception { + Session s = openSession(); + // Get the transaction and set the timeout BEFORE calling begin() + Transaction t = s.getTransaction(); + t.setTimeout( 1 ); + assertEquals( + -1, + ( (SessionImplementor) s ).getJdbcCoordinator().determineRemainingTransactionTimeOutPeriod() + ); + t.begin(); + Thread.sleep( 1000 ); + try { + s.persist( new A() ); + fail( "should have thrown an exception" ); + } + catch (RuntimeException expected){ + exceptionExpectations.onTransactionExceptionOnPersistAndMergeAndFlush( expected ); + } + finally { + t.rollback(); + s.close(); + } + } + + @Test + public void testMergeWithGeneratedValue() throws Exception { + Session s = openSession(); + // Get the transaction and set the timeout BEFORE calling begin() + Transaction t = s.getTransaction(); + t.setTimeout( 1 ); + assertEquals( + -1, + ( (SessionImplementor) s ).getJdbcCoordinator().determineRemainingTransactionTimeOutPeriod() + ); + t.begin(); + Thread.sleep( 1000 ); + try { + s.merge( new A() ); + fail( "should have thrown an exception" ); + } + catch (RuntimeException expected){ + exceptionExpectations.onTransactionExceptionOnPersistAndMergeAndFlush( expected ); + } + finally { + t.rollback(); + s.close(); + } + } + + @Test + public void testSaveWithGeneratedValue() throws Exception { + Session s = openSession(); + // Get the transaction and set the timeout BEFORE calling begin() + Transaction t = s.getTransaction(); + t.setTimeout( 1 ); + assertEquals( + -1, + ( (SessionImplementor) s ).getJdbcCoordinator().determineRemainingTransactionTimeOutPeriod() + ); + t.begin(); + Thread.sleep( 1000 ); + try { + s.save( new A() ); + fail( "should have thrown an exception" ); + } + catch (RuntimeException expected){ + exceptionExpectations.onTransactionExceptionOnSaveAndSaveOrUpdate( expected ); + } + finally { + t.rollback(); + s.close(); + } + } + + @Test + public void testSaveOrUpdateWithGeneratedValue() throws Exception { + Session s = openSession(); + // Get the transaction and set the timeout BEFORE calling begin() + Transaction t = s.getTransaction(); + t.setTimeout( 1 ); + assertEquals( + -1, + ( (SessionImplementor) s ).getJdbcCoordinator().determineRemainingTransactionTimeOutPeriod() + ); + t.begin(); + Thread.sleep( 1000 ); + try { + s.saveOrUpdate( new A() ); + fail( "should have thrown an exception" ); + } + catch (RuntimeException expected){ + exceptionExpectations.onTransactionExceptionOnSaveAndSaveOrUpdate( expected ); + } + finally { + t.rollback(); + s.close(); + } + } + + @Test + public void testFlushWithAssignedValue() throws Exception { + Session s = openSession(); + // Get the transaction and set the timeout BEFORE calling begin() + Transaction t = s.getTransaction(); + t.setTimeout( 1 ); + assertEquals( + -1, + ( (SessionImplementor) s ).getJdbcCoordinator().determineRemainingTransactionTimeOutPeriod() + ); + t.begin(); + Thread.sleep( 1000 ); + try { + s.persist( new B( 1 ) ); + s.flush(); + fail( "should have thrown an exception" ); + } + catch (RuntimeException expected){ + exceptionExpectations.onTransactionExceptionOnPersistAndMergeAndFlush( expected ); + } + finally { + t.rollback(); + s.close(); + } + } + + @Test + public void testCommitWithAssignedValue() throws Exception { + Session s = openSession(); + // Get the transaction and set the timeout BEFORE calling begin() + Transaction t = s.getTransaction(); + t.setTimeout( 1 ); + assertEquals( + -1, + ( (SessionImplementor) s ).getJdbcCoordinator().determineRemainingTransactionTimeOutPeriod() + ); + t.begin(); + Thread.sleep( 1000 ); + try { + s.persist( new B( 1 ) ); + s.getTransaction().commit(); + fail( "should have thrown an exception" ); + } + catch (RuntimeException expected){ + exceptionExpectations.onTransactionExceptionOnCommit( expected ); + } + finally { + t.rollback(); + s.close(); + } + } + + @Entity(name = "A") + public static class A { + @Id + @GeneratedValue + private long id; + } + + @Entity(name = "B") + public static class B { + @Id + private long id; + + public B() { + } + + public B(long id) { + this.id = id; + } + } + +}