From 6cdb0256d41e873b67a8a6ce40a6d1ee5a4b6599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Tue, 15 Oct 2019 15:06:48 +0200 Subject: [PATCH] HHH-13666 Test custom BeforeTransactionCompletionProcess/AfterTransactionCompletionProcess --- .../CustomAfterCompletionTest.java | 133 ++++++++++++++++++ .../CustomBeforeCompletionTest.java | 133 ++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/actionqueue/CustomAfterCompletionTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/actionqueue/CustomBeforeCompletionTest.java diff --git a/hibernate-core/src/test/java/org/hibernate/test/actionqueue/CustomAfterCompletionTest.java b/hibernate-core/src/test/java/org/hibernate/test/actionqueue/CustomAfterCompletionTest.java new file mode 100644 index 0000000000..9806c82066 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/actionqueue/CustomAfterCompletionTest.java @@ -0,0 +1,133 @@ +/* + * 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.actionqueue; + +import java.util.concurrent.atomic.AtomicBoolean; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.HibernateException; +import org.hibernate.action.spi.AfterTransactionCompletionProcess; +import org.hibernate.engine.spi.SharedSessionContractImplementor; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Assert; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +public class CustomAfterCompletionTest extends BaseCoreFunctionalTestCase { + + @Test + @TestForIssue(jiraKey = "HHH-13666") + public void success() { + inSession( session -> { + AtomicBoolean called = new AtomicBoolean( false ); + session.getActionQueue().registerProcess( new AfterTransactionCompletionProcess() { + @Override + public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) { + called.set( true ); + } + } ); + Assert.assertFalse( called.get() ); + inTransaction( session, theSession -> { + theSession.persist( new SimpleEntity( "jack" ) ); + } ); + Assert.assertTrue( called.get() ); + } ); + + // Check that the transaction was committed + inTransaction( session -> { + long count = session.createQuery( "select count(*) from SimpleEntity", Long.class ) + .uniqueResult(); + assertEquals( 1L, count ); + } ); + } + + @Test + @TestForIssue(jiraKey = "HHH-13666") + public void failure() { + try { + inSession( session -> { + session.getActionQueue().registerProcess( new AfterTransactionCompletionProcess() { + @Override + public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) { + throw new RuntimeException( "My exception" ); + } + } ); + inTransaction( session, theSession -> { + theSession.persist( new SimpleEntity( "jack" ) ); + } ); + } ); + Assert.fail( "Expected exception to be thrown" ); + } + catch (Exception e) { + assertThat( e, instanceOf( HibernateException.class ) ); + assertThat( e.getMessage(), containsString( "Unable to perform afterTransactionCompletion callback" ) ); + Throwable cause = e.getCause(); + assertThat( cause, instanceOf( RuntimeException.class ) ); + assertThat( cause.getMessage(), containsString( "My exception" ) ); + + // Make sure that the original message is appended to the wrapping exception's message, for convenience + assertThat( e.getMessage(), containsString( "My exception" ) ); + } + + // Check that the transaction was committed + inTransaction( session -> { + long count = session.createQuery( "select count(*) from SimpleEntity", Long.class ) + .uniqueResult(); + assertEquals( 1L, count ); + } ); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { SimpleEntity.class }; + } + + @Override + protected boolean isCleanupTestDataRequired() { + return true; + } + + @Entity(name = "SimpleEntity") + public static class SimpleEntity { + @Id + @GeneratedValue + private Integer id; + + private String name; + + SimpleEntity() { + } + + SimpleEntity(String name) { + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/actionqueue/CustomBeforeCompletionTest.java b/hibernate-core/src/test/java/org/hibernate/test/actionqueue/CustomBeforeCompletionTest.java new file mode 100644 index 0000000000..ef778b4157 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/actionqueue/CustomBeforeCompletionTest.java @@ -0,0 +1,133 @@ +/* + * 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.actionqueue; + +import java.util.concurrent.atomic.AtomicBoolean; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.HibernateException; +import org.hibernate.action.spi.BeforeTransactionCompletionProcess; +import org.hibernate.engine.spi.SessionImplementor; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Assert; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +public class CustomBeforeCompletionTest extends BaseCoreFunctionalTestCase { + + @Test + @TestForIssue(jiraKey = "HHH-13666") + public void success() { + inSession( session -> { + AtomicBoolean called = new AtomicBoolean( false ); + session.getActionQueue().registerProcess( new BeforeTransactionCompletionProcess() { + @Override + public void doBeforeTransactionCompletion(SessionImplementor session) { + called.set( true ); + } + } ); + Assert.assertFalse( called.get() ); + inTransaction( session, theSession -> { + theSession.persist( new SimpleEntity( "jack" ) ); + } ); + Assert.assertTrue( called.get() ); + } ); + + // Check that the transaction was committed + inTransaction( session -> { + long count = session.createQuery( "select count(*) from SimpleEntity", Long.class ) + .uniqueResult(); + assertEquals( 1L, count ); + } ); + } + + @Test + @TestForIssue(jiraKey = "HHH-13666") + public void failure() { + try { + inSession( session -> { + session.getActionQueue().registerProcess( new BeforeTransactionCompletionProcess() { + @Override + public void doBeforeTransactionCompletion(SessionImplementor session) { + throw new RuntimeException( "My exception" ); + } + } ); + inTransaction( session, theSession -> { + theSession.persist( new SimpleEntity( "jack" ) ); + } ); + } ); + Assert.fail( "Expected exception to be thrown" ); + } + catch (Exception e) { + assertThat( e, instanceOf( HibernateException.class ) ); + assertThat( e.getMessage(), containsString( "Unable to perform beforeTransactionCompletion callback" ) ); + Throwable cause = e.getCause(); + assertThat( cause, instanceOf( RuntimeException.class ) ); + assertThat( cause.getMessage(), containsString( "My exception" ) ); + + // Make sure that the original message is appended to the wrapping exception's message, for convenience + assertThat( e.getMessage(), containsString( "My exception" ) ); + } + + // Check that the transaction was rolled back + inTransaction( session -> { + long count = session.createQuery( "select count(*) from SimpleEntity", Long.class ) + .uniqueResult(); + assertEquals( 0L, count ); + } ); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { SimpleEntity.class }; + } + + @Override + protected boolean isCleanupTestDataRequired() { + return true; + } + + @Entity(name = "SimpleEntity") + public static class SimpleEntity { + @Id + @GeneratedValue + private Integer id; + + private String name; + + SimpleEntity() { + } + + SimpleEntity(String name) { + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +}