diff --git a/hibernate-reactive-core/build.gradle b/hibernate-reactive-core/build.gradle index aa698af4b..297da3fd3 100644 --- a/hibernate-reactive-core/build.gradle +++ b/hibernate-reactive-core/build.gradle @@ -26,10 +26,6 @@ dependencies { implementation "io.vertx:vertx-sql-client:${vertxVersion}" // Testing - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' - testRuntimeOnly 'org.junit.vintage:junit-vintage-engine' - testImplementation 'org.assertj:assertj-core:3.13.2' testImplementation "io.vertx:vertx-unit:${vertxVersion}" @@ -94,9 +90,6 @@ tasks.withType(Test) { // Example: // gradle test -Pdb=MySQL test { - // Enable JUnit 5 - useJUnitPlatform() - def selectedDb = project.hasProperty( 'db' ) ? project.getProperty( 'db' ) : 'PostgreSQL' diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BaseReactiveTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BaseReactiveTest.java index 2ac43510e..5cb4df8bd 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BaseReactiveTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BaseReactiveTest.java @@ -5,12 +5,11 @@ */ package org.hibernate.reactive; -import io.smallrye.mutiny.Uni; -import io.vertx.ext.unit.Async; -import io.vertx.ext.unit.TestContext; -import io.vertx.ext.unit.junit.RunTestOnContext; -import io.vertx.ext.unit.junit.Timeout; -import io.vertx.ext.unit.junit.VertxUnitRunner; +import java.util.Arrays; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; @@ -21,21 +20,33 @@ import org.hibernate.reactive.containers.DatabaseConfiguration.DBType; import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.pool.ReactiveConnection; -import org.hibernate.reactive.pool.ReactiveConnectionPool; import org.hibernate.reactive.provider.ReactiveServiceRegistryBuilder; import org.hibernate.reactive.provider.Settings; import org.hibernate.reactive.provider.service.ReactiveGenerationTarget; import org.hibernate.reactive.stage.Stage; +import org.hibernate.reactive.testing.SessionFactoryManager; import org.hibernate.reactive.vertx.VertxInstance; import org.hibernate.tool.schema.spi.SchemaManagementTool; + import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Rule; import org.junit.runner.RunWith; -import java.util.concurrent.CompletionStage; +import io.smallrye.mutiny.Uni; +import io.vertx.core.Promise; +import io.vertx.core.Vertx; +import io.vertx.core.VertxOptions; +import io.vertx.ext.unit.Async; +import io.vertx.ext.unit.TestContext; +import io.vertx.ext.unit.junit.RunTestOnContext; +import io.vertx.ext.unit.junit.Timeout; +import io.vertx.ext.unit.junit.VertxUnitRunner; import static org.hibernate.reactive.containers.DatabaseConfiguration.dbType; +import static org.hibernate.reactive.util.impl.CompletionStages.loop; /** * Base class for unit tests that need a connection to the selected db and @@ -53,20 +64,31 @@ @RunWith(VertxUnitRunner.class) public abstract class BaseReactiveTest { + public static SessionFactoryManager factoryManager = new SessionFactoryManager(); + @Rule public Timeout rule = Timeout.seconds( 5 * 60 ); - @Rule - public RunTestOnContext vertxContextRule = new RunTestOnContext(); + @ClassRule + public static RunTestOnContext vertxContextRule = new RunTestOnContext( () -> { + VertxOptions options = new VertxOptions(); + options.setBlockedThreadCheckInterval( 5 ); + options.setBlockedThreadCheckIntervalUnit( TimeUnit.MINUTES ); + Vertx vertx = Vertx.vertx( options ); + return vertx; + } ); - private AutoCloseable session; + private AutoCloseable session, statelessSession; private ReactiveConnection connection; - private org.hibernate.SessionFactory sessionFactory; - private ReactiveConnectionPool poolProvider; protected static void test(TestContext context, CompletionStage work) { - // this will be added to TestContext in the next vert.x release - Async async = context.async(); + test( context.async(), context, work ); + } + + /** + * For when we need to create the {@link Async} in advance + */ + protected static void test(Async async, TestContext context, CompletionStage work) { work.whenComplete( (res, err) -> { if ( res instanceof Stage.Session ) { Stage.Session s = (Stage.Session) res; @@ -84,7 +106,13 @@ protected static void test(TestContext context, CompletionStage work) { } protected static void test(TestContext context, Uni uni) { - Async async = context.async(); + test( context.async(), context, uni ); + } + + /** + * For when we need to create the {@link Async} in advance + */ + protected static void test(Async async, TestContext context, Uni uni) { uni.subscribe().with( res -> { if ( res instanceof Mutiny.Session) { @@ -116,8 +144,57 @@ protected Configuration constructConfiguration() { return configuration; } + public CompletionStage deleteEntities(Class... entities) { + return deleteEntities( Arrays.stream( entities ) + .map( BaseReactiveTest::defaultEntityName ) + .collect( Collectors.toList() ) + .toArray( new String[entities.length] ) ); + } + + private static String defaultEntityName(Class aClass) { + int index = aClass.getName().lastIndexOf( '.' ); + index = index > -1 ? index + 1 : 0; + return aClass.getName().substring( index ); + } + + public CompletionStage deleteEntities(String... entities) { + return getSessionFactory() + .withTransaction( (s, tx) -> loop( entities, name -> s + .createQuery( "from " + name ).getResultList() + .thenCompose( list -> s.remove( list.toArray( new Object[list.size()] ) ) ) ) ); + } + @Before public void before(TestContext context) { + Async async = context.async(); + vertxContextRule.vertx() + .executeBlocking( + // schema generation is a blocking operation and so it causes an + // exception when run on the Vert.x event loop. So call it using + // Vertx.executeBlocking() + this::startFactoryManager, + event -> { + if ( event.succeeded() ) { + async.complete(); + } + else { + context.fail( event.cause() ); + } + } + ); + } + + private void startFactoryManager(Promise p) { + try { + factoryManager.start( () -> createHibernateSessionFactory() ); + p.complete(); + } + catch (Throwable e) { + p.fail( e ); + } + } + + private SessionFactory createHibernateSessionFactory() { Configuration configuration = constructConfiguration(); StandardServiceRegistryBuilder builder = new ReactiveServiceRegistryBuilder() .addService( VertxInstance.class, (VertxInstance) () -> vertxContextRule.vertx() ) @@ -125,24 +202,8 @@ public void before(TestContext context) { addServices( builder ); StandardServiceRegistry registry = builder.build(); configureServices( registry ); - - // schema generation is a blocking operation and so it causes an - // exception when run on the Vert.x event loop. So call it using - // Vertx.executeBlocking() - Async async = context.async(); - vertxContextRule.vertx().executeBlocking( - p -> p.complete( configuration.buildSessionFactory( registry ) ), - r -> { - if ( r.failed() ) { - context.fail( r.cause() ); - } - else { - sessionFactory = r.result(); - poolProvider = registry.getService( ReactiveConnectionPool.class ); - async.complete(); - } - } - ); + SessionFactory sessionFactory = configuration.buildSessionFactory( registry ); + return sessionFactory; } protected void addServices(StandardServiceRegistryBuilder builder) {} @@ -179,6 +240,11 @@ public void after(TestContext context) { session.close(); session = null; } + if ( statelessSession != null && statelessSession.isOpen() ) { + statelessSession.close(); + statelessSession = null; + } + if ( connection != null ) { try { connection.close(); @@ -188,14 +254,15 @@ public void after(TestContext context) { connection = null; } } + } - if ( sessionFactory != null ) { - sessionFactory.close(); - } + @AfterClass + public static void closeFactory() { + factoryManager.stop(); } protected Stage.SessionFactory getSessionFactory() { - return sessionFactory.unwrap( Stage.SessionFactory.class ); + return factoryManager.getHibernateSessionFactory().unwrap( Stage.SessionFactory.class ); } /** @@ -212,8 +279,17 @@ protected Stage.Session openSession() { return newSession; } + protected Stage.StatelessSession openStatelessSession() { + if ( statelessSession != null && statelessSession.isOpen() ) { + statelessSession.close(); + } + Stage.StatelessSession newSession = getSessionFactory().openStatelessSession(); + this.statelessSession = newSession; + return newSession; + } + protected CompletionStage connection() { - return poolProvider.getConnection().thenApply( c -> connection = c ); + return factoryManager.getReactiveConnectionPool().getConnection().thenApply( c -> connection = c ); } /** @@ -230,8 +306,16 @@ protected Mutiny.Session openMutinySession() { return newSession; } - protected Mutiny.SessionFactory getMutinySessionFactory() { - return sessionFactory.unwrap( Mutiny.SessionFactory.class ); + protected Mutiny.StatelessSession openMutinyStatelessSession() { + if ( statelessSession != null ) { + statelessSession.close(); + } + Mutiny.StatelessSession newSession = getMutinySessionFactory().openStatelessSession(); + this.statelessSession = newSession; + return newSession; } + protected Mutiny.SessionFactory getMutinySessionFactory() { + return factoryManager.getHibernateSessionFactory().unwrap( Mutiny.SessionFactory.class ); + } } diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BatchFetchTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BatchFetchTest.java index d6f9903a5..c0935b078 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BatchFetchTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BatchFetchTest.java @@ -10,6 +10,8 @@ import org.hibernate.LockMode; import org.hibernate.annotations.BatchSize; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.CascadeType; @@ -45,6 +47,13 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, getSessionFactory() + .withTransaction( (s, t) -> s.createQuery( "delete from Element" ).executeUpdate() + .thenCompose( v -> s.createQuery( "delete from Node" ).executeUpdate() ) ) ); + } + @Test public void testQuery(TestContext context) { diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BatchQueryOnConnectionTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BatchQueryOnConnectionTest.java index e2d8bccd1..838b82e6b 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BatchQueryOnConnectionTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BatchQueryOnConnectionTest.java @@ -15,6 +15,7 @@ import org.hibernate.cfg.Configuration; import org.hibernate.reactive.pool.ReactiveConnection; +import org.junit.After; import org.junit.Test; import io.vertx.ext.unit.TestContext; @@ -24,6 +25,11 @@ public class BatchQueryOnConnectionTest extends BaseReactiveTest { private static final int BATCH_SIZE = 20; + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "DataPoint" ) ); + } + @Test public void testBatchInsertSizeEqMultiple(TestContext context) { final List> paramsBatches = doBatchInserts( context, 50, BATCH_SIZE ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CacheTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CacheTest.java index 9ae74ae95..98947b254 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CacheTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CacheTest.java @@ -9,6 +9,8 @@ import org.hibernate.annotations.Cache; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; + +import org.junit.After; import org.junit.Test; import javax.persistence.Cacheable; @@ -32,6 +34,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDB(TestContext context) { + getSessionFactory().close(); + } + @Test public void testCacheWithHQL(TestContext context) { org.hibernate.Cache cache = getSessionFactory().getCache(); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CompletionStagesTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CompletionStagesTest.java index 80c9215a6..ffd3c68bc 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CompletionStagesTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CompletionStagesTest.java @@ -11,14 +11,6 @@ import java.util.concurrent.CompletionStage; import java.util.stream.IntStream; - -import static java.util.Arrays.asList; -import static java.util.Arrays.stream; -import static org.hibernate.reactive.util.impl.CompletionStages.*; -import static org.hibernate.reactive.util.impl.CompletionStages.total; -import static org.hibernate.reactive.util.impl.CompletionStages.loop; -import static org.hibernate.reactive.util.impl.CompletionStages.loopWithoutTrampoline; - import org.junit.Test; import org.junit.runner.RunWith; @@ -26,7 +18,14 @@ import io.vertx.ext.unit.TestContext; import io.vertx.ext.unit.junit.VertxUnitRunner; +import static java.util.Arrays.asList; +import static java.util.Arrays.stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.hibernate.reactive.util.impl.CompletionStages.completedFuture; +import static org.hibernate.reactive.util.impl.CompletionStages.loop; +import static org.hibernate.reactive.util.impl.CompletionStages.loopWithoutTrampoline; +import static org.hibernate.reactive.util.impl.CompletionStages.total; +import static org.hibernate.reactive.util.impl.CompletionStages.voidFuture; /** * Tests the utility methods in {@link org.hibernate.reactive.util.impl.CompletionStages} diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeListTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeListTest.java index 21234bb2b..e52d36f67 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeListTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeListTest.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.CompletionStage; -import java.util.stream.Collectors; import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -17,15 +16,15 @@ import javax.persistence.Table; import org.hibernate.cfg.Configuration; -import org.hibernate.reactive.mutiny.Mutiny; -import org.hibernate.reactive.stage.Stage; +import org.junit.After; import org.junit.Before; import org.junit.Test; import io.smallrye.mutiny.Uni; import io.vertx.ext.unit.TestContext; -import org.assertj.core.api.Assertions; + +import static org.assertj.core.api.Assertions.assertThat; /** * Tests @{@link ElementCollection} on a {@link List} of basic types. @@ -57,388 +56,316 @@ public void populateDb(TestContext context) { List phones = Arrays.asList( "999-999-9999", "111-111-1111", "123-456-7890" ); thePerson = new Person( 7242000, "Claude", phones ); - Mutiny.Session session = openMutinySession(); - test( context, session.persist( thePerson ).call( session::flush ) ); + test( context, getMutinySessionFactory().withTransaction( (s, t) -> s.persist( thePerson ) ) ); + } + + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); } @Test public void persistWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - Person johnny = new Person( 999, "Johnny English", Arrays.asList( "888", "555" ) ); - test ( - context, - session.persist( johnny ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, johnny.getId() ) ) - .invoke( found -> assertPhones( context, found, "888", "555" ) ) + test( context, getMutinySessionFactory() + .withTransaction( (s, t) -> s.persist( johnny ) ) + .chain( () -> openMutinySession().find( Person.class, johnny.getId() ) ) + .invoke( found -> assertPhones( context, found, "888", "555" ) ) ); } @Test public void findEntityWithElementCollectionWithStageAPI(TestContext context) { - Stage.Session session = openSession(); - - test ( - context, - session.find( Person.class, thePerson.getId() ) - .thenAccept( found -> assertPhones( context, found, "999-999-9999", "111-111-1111", "123-456-7890" ) ) + test( context, openSession() + .find( Person.class, thePerson.getId() ) + .thenAccept( found -> assertPhones( context, found, "999-999-9999", "111-111-1111", "123-456-7890" ) ) ); } @Test public void findEntityWithElementCollectionWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - - test ( - context, - session.find( Person.class, thePerson.getId() ) - .invoke( found -> assertPhones( context, found, "999-999-9999", "111-111-1111", "123-456-7890" ) ) + test( context, openMutinySession() + .find( Person.class, thePerson.getId() ) + .invoke( found -> assertPhones( context, found, "999-999-9999", "111-111-1111", "123-456-7890" ) ) ); } @Test public void persistCollectionWithDuplicatesWithStageAPI(TestContext context) { - Stage.Session session = openSession(); - Person thomas = new Person( 7, "Thomas Reaper", Arrays.asList( "111", "111", "111", "111" ) ); - test( - context, - session.persist( thomas ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thomas.getId() ) ) - .thenAccept( found -> assertPhones( context, found, "111", "111", "111", "111" ) ) + test( context, getSessionFactory() + .withTransaction( (s, t) -> s.persist( thomas ) ) + .thenCompose( v -> openSession().find( Person.class, thomas.getId() ) ) + .thenAccept( found -> assertPhones( context, found, "111", "111", "111", "111" ) ) ); } @Test public void persistCollectionWithDuplicatesWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - Person thomas = new Person( 567, "Thomas Reaper", Arrays.asList( "111", "111", "111", "111" ) ); - test( - context, - session.persist( thomas ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thomas.getId() ) ) - .invoke( found -> assertPhones( context, found, "111", "111", "111", "111" ) ) + test( context, getMutinySessionFactory() + .withTransaction( (s, t) -> s.persist( thomas ) ) + .chain( () -> openMutinySession().find( Person.class, thomas.getId() ) ) + .invoke( found -> assertPhones( context, found, "111", "111", "111", "111" ) ) ); } @Test public void updateCollectionWithDuplicatesWithStageAPI(TestContext context) { - Stage.Session session = openSession(); - Person thomas = new Person( 47, "Thomas Reaper", Arrays.asList( "000", "000", "000", "000" ) ); - test( - context, - session.persist( thomas ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> { - Stage.Session newSession = openSession(); - return newSession.find( Person.class, thomas.getId() ) - // Change one of the element in the collection - .thenAccept( found -> { - found.getPhones().set( 1, "47" ); - found.getPhones().set( 3, "47" ); - } ) - .thenCompose( ignore -> newSession.flush() ) - .thenCompose( ignore -> openSession().find( Person.class, thomas.getId() ) ) - .thenAccept( found -> assertPhones( context, found, "000", "47", "000", "47" ) ); - } ) + test( context, getSessionFactory() + .withTransaction( (s, t) -> s.persist( thomas ) ) + .thenCompose( v -> getSessionFactory().withTransaction( (s, t) -> s + .find( Person.class, thomas.getId() ) + // Change one of the element in the collection + .thenAccept( found -> { + found.getPhones().set( 1, "47" ); + found.getPhones().set( 3, "47" ); + } ) ) ) + .thenCompose( v -> openSession().find( Person.class, thomas.getId() ) ) + .thenAccept( found -> assertPhones( context, found, "000", "47", "000", "47" ) ) ); } @Test public void updateCollectionWithDuplicatesWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - Person thomas = new Person( 47, "Thomas Reaper", Arrays.asList( "000", "000", "000", "000" ) ); - test( - context, - session.persist( thomas ) - .call( session::flush ) - .chain( () -> { - Mutiny.Session newSession = openMutinySession(); - return newSession.find( Person.class, thomas.getId() ) - // Change a couple of the elements in the collection - .invoke( found -> { - found.getPhones().set( 1, "47" ); - found.getPhones().set( 3, "47" ); - } ) - .call( newSession::flush ) - .chain( () -> openMutinySession().find( Person.class, thomas.getId() ) ) - .invoke( found -> assertPhones( context, found, "000", "47", "000", "47" ) ); - } ) + test( context, getMutinySessionFactory() + .withTransaction( (s, t) -> s.persist( thomas ) ) + .chain( () -> getMutinySessionFactory() + .withTransaction( (session, tx) -> session + .find( Person.class, thomas.getId() ) + // Change a couple of the elements in the collection + .invoke( found -> { + found.getPhones().set( 1, "47" ); + found.getPhones().set( 3, "47" ); + } ) ) + ) + .chain( () -> openMutinySession().find( Person.class, thomas.getId() ) ) + .invoke( found -> assertPhones( context, found, "000", "47", "000", "47" ) ) ); } @Test public void deleteElementsFromCollectionWithDuplicatesWithStageAPI(TestContext context) { - Stage.Session session = openSession(); - Person thomas = new Person( 47, "Thomas Reaper", Arrays.asList( "000", "000", "000", "000" ) ); - test( - context, - session.persist( thomas ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> { - Stage.Session newSession = openSession(); - return newSession.find( Person.class, thomas.getId() ) - // Change one of the element in the collection - .thenAccept( found -> { - // it doesn't matter which elements are deleted because they are all equal - found.getPhones().remove( 1 ); - found.getPhones().remove( 2 ); - } ) - .thenCompose( ignore -> newSession.flush() ) - .thenCompose( ignore -> openSession().find( Person.class, thomas.getId() ) ) - .thenAccept( found -> assertPhones( context, found, "000", "000" ) ); - } ) + test( context, getSessionFactory() + .withTransaction( (s, t) -> s.persist( thomas ) ) + .thenCompose( v -> getSessionFactory() + .withTransaction( (session, tx) -> session + .find( Person.class, thomas.getId() ) + // Change one of the element in the collection + .thenAccept( found -> { + // it doesn't matter which elements are deleted because they are all equal + found.getPhones().remove( 1 ); + found.getPhones().remove( 2 ); + } ) + ) + ) + .thenCompose( v -> openSession().find( Person.class, thomas.getId() ) ) + .thenAccept( found -> assertPhones( context, found, "000", "000" ) ) ); } @Test public void deleteElementsFromCollectionWithDuplicatesWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - Person thomas = new Person( 47, "Thomas Reaper", Arrays.asList( "000", "000", "000", "000" ) ); - test( - context, - session.persist( thomas ) - .call( session::flush ) - .chain( () -> { - Mutiny.Session newSession = openMutinySession(); - return newSession.find( Person.class, thomas.getId() ) - // Change one of the element in the collection - .invoke( found -> { - // it doesn't matter which elements are deleted because they are all equal - found.getPhones().remove( 1 ); - found.getPhones().remove( 2 ); - } ) - .call( newSession::flush ) - .chain( () -> openMutinySession().find( Person.class, thomas.getId() ) ) - .invoke( found -> assertPhones( context, found, "000", "000" ) ); - } ) + test( context, getMutinySessionFactory() + .withTransaction( (s, t) -> s.persist( thomas ) ) + .chain( () -> getMutinySessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thomas.getId() ) + // Change one of the element in the collection + .invoke( found -> { + // it doesn't matter which elements are deleted because they are all equal + found.getPhones().remove( 1 ); + found.getPhones().remove( 2 ); + } ) + ) + ) + .chain( () -> getMutinySessionFactory().withSession( session -> session.find( Person.class, thomas.getId() ) ) ) + .invoke( found -> assertPhones( context, found, "000", "000" ) ) ); } @Test public void addOneElementWithStageAPI(TestContext context) { - Stage.Session session = openSession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) // Remove one element from the collection - .thenAccept( foundPerson -> foundPerson.getPhones().add( "000" ) ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) - .thenAccept( updatedPerson -> - assertPhones( - context, - updatedPerson, - "999-999-9999", "111-111-1111", "123-456-7890", "000" - ) ) + .thenAccept( foundPerson -> foundPerson.getPhones().add( "000" ) ) ) + .thenCompose( v -> getSessionFactory().withSession( session -> session.find( Person.class, thePerson.getId() ) ) ) + .thenAccept( updatedPerson -> assertPhones( context, updatedPerson, "999-999-9999", "111-111-1111", "123-456-7890", "000" ) ) ); } @Test public void addOneElementWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getMutinySessionFactory() + .withTransaction( (session, tx) -> session + .find( Person.class, thePerson.getId() ) // Remove one element from the collection - .invoke( foundPerson -> foundPerson.getPhones().add( "000" ) ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( updatedPerson -> - assertPhones( - context, - updatedPerson, - "999-999-9999", "111-111-1111", "123-456-7890", "000" - ) ) + .invoke( foundPerson -> foundPerson.getPhones().add( "000" ) ) ) + .chain( () -> getMutinySessionFactory().withSession( session -> session.find( Person.class, thePerson.getId() ) ) ) + .invoke( updatedPerson -> assertPhones( context, updatedPerson, "999-999-9999", "111-111-1111", "123-456-7890", "000" ) ) ); } @Test public void removeOneElementWithStageAPI(TestContext context) { - Stage.Session session = openSession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getSessionFactory() + .withTransaction( (s, tx) -> s + .find( Person.class, thePerson.getId() ) // Remove one element from the collection - .thenAccept( foundPerson -> foundPerson.getPhones().remove( "111-111-1111" ) ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) - .thenAccept( updatedPerson -> assertPhones( context, updatedPerson, "999-999-9999", "123-456-7890" ) ) + .thenAccept( foundPerson -> foundPerson.getPhones().remove( "111-111-1111" ) ) ) + .thenCompose( v -> getSessionFactory().withSession( session -> session.find( Person.class, thePerson.getId() ) ) ) + .thenAccept( updatedPerson -> assertPhones( context, updatedPerson, "999-999-9999", "123-456-7890" ) ) ); } @Test public void removeOneElementWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getMutinySessionFactory() + .withTransaction( (s, tx) -> s + .find( Person.class, thePerson.getId() ) // Remove one element from the collection .invoke( foundPerson -> foundPerson.getPhones().remove( "111-111-1111" ) ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( updatedPerson -> assertPhones( context, updatedPerson, "999-999-9999", "123-456-7890" ) ) + ) + .chain( () -> getMutinySessionFactory().withSession( session -> session.find( Person.class, thePerson.getId() ) ) ) + .invoke( updatedPerson -> assertPhones( context, updatedPerson, "999-999-9999", "123-456-7890" ) ) ); } @Test public void clearCollectionOfElementsWithStageAPI(TestContext context){ - Stage.Session session = openSession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .thenAccept( foundPerson -> { context.assertFalse( foundPerson.getPhones().isEmpty() ); foundPerson.getPhones().clear(); } ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) - .thenAccept( changedPerson -> context.assertTrue( changedPerson.getPhones().isEmpty() ) ) ) + .thenCompose( v -> getSessionFactory().withSession( session -> session.find( Person.class, thePerson.getId() ) ) ) + .thenAccept( changedPerson -> context.assertTrue( changedPerson.getPhones().isEmpty() ) ) ); } @Test public void clearCollectionOfElementsWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .invoke( foundPerson -> { context.assertFalse( foundPerson.getPhones().isEmpty() ); foundPerson.getPhones().clear(); } ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( changedPerson -> context.assertTrue( changedPerson.getPhones().isEmpty() ) ) + ) + .chain( () -> getMutinySessionFactory().withSession( session -> session.find( Person.class, thePerson.getId() ) ) ) + .invoke( changedPerson -> context.assertTrue( changedPerson.getPhones().isEmpty() ) ) ); } @Test public void removeAndAddElementWithStageAPI(TestContext context){ - Stage.Session session = openSession(); - - test ( - context, - session.find( Person.class, thePerson.getId()) + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .thenAccept( foundPerson -> { - context.assertNotNull( foundPerson ); - foundPerson.getPhones().remove( "111-111-1111" ); - foundPerson.getPhones().add( "000" ); - } ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) - .thenAccept( changedPerson -> assertPhones( context, changedPerson, "999-999-9999", "123-456-7890", "000" ) ) + context.assertNotNull( foundPerson ); + foundPerson.getPhones().remove( "111-111-1111" ); + foundPerson.getPhones().add( "000" ); + } ) + ) + .thenCompose( v -> getSessionFactory().withSession( session -> session.find( Person.class, thePerson.getId() ) ) ) + .thenAccept( changedPerson -> assertPhones( context, changedPerson, "999-999-9999", "123-456-7890", "000" ) ) ); } @Test - public void removeAndAddElementWithMutinyAPI(TestContext context){ - Mutiny.Session session = openMutinySession(); - - test ( - context, - session.find( Person.class, thePerson.getId()) + public void removeAndAddElementWithMutinyAPI(TestContext context) { + test( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .invoke( foundPerson -> { context.assertNotNull( foundPerson ); foundPerson.getPhones().remove( "111-111-1111" ); foundPerson.getPhones().add( "000" ); } ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( person -> assertPhones( context, person, "999-999-9999", "123-456-7890", "000" ) ) + ) + .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) + .invoke( person -> assertPhones( context, person, "999-999-9999", "123-456-7890", "000" ) ) ); } @Test - public void setNewElementCollectionWithStageAPI(TestContext context){ - Stage.Session session = openSession(); - - test ( - context, - session.find( Person.class, thePerson.getId()) + public void setNewElementCollectionWithStageAPI(TestContext context) { + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .thenAccept( foundPerson -> { context.assertNotNull( foundPerson ); context.assertFalse( foundPerson.getPhones().isEmpty() ); foundPerson.setPhones( Arrays.asList( "555" ) ); } ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thePerson.getId()) ) - .thenAccept( changedPerson -> assertPhones( context, changedPerson, "555" ) ) + ) + .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) + .thenAccept( changedPerson -> assertPhones( context, changedPerson, "555" ) ) ); } @Test public void setNewElementCollectionWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .invoke( foundPerson -> { context.assertNotNull( foundPerson ); context.assertFalse( foundPerson.getPhones().isEmpty() ); foundPerson.setPhones( Arrays.asList( "555" ) ); } ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( changedPerson -> assertPhones( context, changedPerson, "555" ) ) + ) + .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) + .invoke( changedPerson -> assertPhones( context, changedPerson, "555" ) ) ); } @Test public void removePersonWithStageAPI(TestContext context) { - Stage.Session session = openSession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) // remove thePerson entity and flush .thenCompose( foundPerson -> session.remove( foundPerson ) ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) - .thenAccept( nullPerson -> context.assertNull( nullPerson ) ) - // Check with native query that the table is empty - .thenCompose( v -> selectFromPhonesWithStage( thePerson ) ) - .thenAccept( resultList -> context.assertTrue( resultList.isEmpty() ) ) + ) + .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) + .thenAccept( nullPerson -> context.assertNull( nullPerson ) ) + // Check with native query that the table is empty + .thenCompose( v -> selectFromPhonesWithStage( thePerson ) ) + .thenAccept( resultList -> context.assertTrue( resultList.isEmpty() ) ) ); } @Test public void removePersonWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getMutinySessionFactory() + .withTransaction( (session, tx) -> session + .find( Person.class, thePerson.getId() ) .call( session::remove ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( nullPerson -> context.assertNull( nullPerson ) ) - // Check with native query that the table is empty - .chain( () -> selectFromPhonesWithMutiny( thePerson ) ) - .invoke( resultList -> context.assertTrue( resultList.isEmpty() ) ) + ) + .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) + .invoke( nullPerson -> context.assertNull( nullPerson ) ) + // Check with native query that the table is empty + .chain( () -> selectFromPhonesWithMutiny( thePerson ) ) + .invoke( resultList -> context.assertTrue( resultList.isEmpty() ) ) ); } @@ -446,17 +373,14 @@ public void removePersonWithMutinyAPI(TestContext context) { public void persistAnotherPersonWithStageAPI(TestContext context) { Person secondPerson = new Person( 9910000, "Kitty", Arrays.asList( "222-222-2222", "333-333-3333" ) ); - Stage.Session session = openSession(); - - test( context, - session.persist( secondPerson ) - .thenCompose( v -> session.flush() ) - // Check new person collection - .thenCompose( v -> openSession().find( Person.class, secondPerson.getId() ) ) - .thenAccept( foundPerson -> assertPhones( context, foundPerson, "222-222-2222", "333-333-3333" ) ) - // Check initial person collection hasn't changed - .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) - .thenAccept( foundPerson -> assertPhones( context, foundPerson, "999-999-9999", "111-111-1111", "123-456-7890" ) ) + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session.persist( secondPerson ) ) + // Check new person collection + .thenCompose( v -> openSession().find( Person.class, secondPerson.getId() ) ) + .thenAccept( foundPerson -> assertPhones( context, foundPerson, "222-222-2222", "333-333-3333" ) ) + // Check initial person collection hasn't changed + .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) + .thenAccept( foundPerson -> assertPhones( context, foundPerson, "999-999-9999", "111-111-1111", "123-456-7890" ) ) ); } @@ -464,17 +388,14 @@ public void persistAnotherPersonWithStageAPI(TestContext context) { public void persistAnotherPersonWithMutinyAPI(TestContext context) { Person secondPerson = new Person( 9910000, "Kitty", Arrays.asList( "222-222-2222", "333-333-3333" ) ); - Mutiny.Session session = openMutinySession(); - - test( context, - session.persist( secondPerson ) - .call( session::flush ) - // Check new person collection - .chain( () -> openMutinySession().find( Person.class, secondPerson.getId() ) ) - .invoke( foundPerson -> assertPhones( context, foundPerson, "222-222-2222", "333-333-3333" ) ) - // Check initial person collection hasn't changed - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( foundPerson -> assertPhones( context, foundPerson, "999-999-9999", "111-111-1111", "123-456-7890" ) ) + test( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session.persist( secondPerson ) ) + // Check new person collection + .chain( () -> openMutinySession().find( Person.class, secondPerson.getId() ) ) + .invoke( foundPerson -> assertPhones( context, foundPerson, "222-222-2222", "333-333-3333" ) ) + // Check initial person collection hasn't changed + .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) + .invoke( foundPerson -> assertPhones( context, foundPerson, "999-999-9999", "111-111-1111", "123-456-7890" ) ) ); } @@ -482,15 +403,12 @@ public void persistAnotherPersonWithMutinyAPI(TestContext context) { public void persistCollectionOfNullsWithStageAPI(TestContext context) { Person secondPerson = new Person( 9910000, "Kitty", Arrays.asList( null, null ) ); - Stage.Session session = openSession(); - - test( context, - session.persist( secondPerson ) - .thenCompose( v -> session.flush() ) - // Check new person collection - .thenCompose( v -> openSession().find( Person.class, secondPerson.getId() ) ) - // Null values don't get persisted - .thenAccept( foundPerson -> context.assertTrue( foundPerson.getPhones().isEmpty() ) ) + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session.persist( secondPerson ) ) + // Check new person collection + .thenCompose( v -> openSession().find( Person.class, secondPerson.getId() ) ) + // Null values don't get persisted + .thenAccept( foundPerson -> context.assertTrue( foundPerson.getPhones().isEmpty() ) ) ); } @@ -498,15 +416,12 @@ public void persistCollectionOfNullsWithStageAPI(TestContext context) { public void persistCollectionOfNullsWithMutinyAPI(TestContext context) { Person secondPerson = new Person( 9910000, "Kitty", Arrays.asList( null, null ) ); - Mutiny.Session session = openMutinySession(); - - test( context, - session.persist( secondPerson ) - .call( session::flush ) - // Check new person collection - .chain( () -> openMutinySession().find( Person.class, secondPerson.getId() ) ) - // Null values don't get persisted - .invoke( foundPerson -> context.assertTrue( foundPerson.getPhones().isEmpty() ) ) + test( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session.persist( secondPerson ) ) + // Check new person collection + .chain( () -> openMutinySession().find( Person.class, secondPerson.getId() ) ) + // Null values don't get persisted + .invoke( foundPerson -> context.assertTrue( foundPerson.getPhones().isEmpty() ) ) ); } @@ -514,15 +429,12 @@ public void persistCollectionOfNullsWithMutinyAPI(TestContext context) { public void persistCollectionWithNullsWithStageAPI(TestContext context) { Person secondPerson = new Person( 9910000, "Kitty", Arrays.asList( null, "567", null ) ); - Stage.Session session = openSession(); - - test( context, - session.persist( secondPerson ) - .thenCompose( v -> session.flush() ) - // Check new person collection - .thenCompose( v -> openSession().find( Person.class, secondPerson.getId() ) ) - // Null values don't get persisted - .thenAccept( foundPerson -> assertPhones( context, foundPerson, "567" ) ) + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session.persist( secondPerson ) ) + // Check new person collection + .thenCompose( v -> openSession().find( Person.class, secondPerson.getId() ) ) + // Null values don't get persisted + .thenAccept( foundPerson -> assertPhones( context, foundPerson, "567" ) ) ); } @@ -530,47 +442,42 @@ public void persistCollectionWithNullsWithStageAPI(TestContext context) { public void persistCollectionWithNullsWithMutinyAPI(TestContext context) { Person secondPerson = new Person( 9910000, "Kitty", Arrays.asList( null, "567", null ) ); - Mutiny.Session session = openMutinySession(); - - test( context, - session.persist( secondPerson ) - .call( session::flush ) - // Check new person collection - .chain( () -> openMutinySession().find( Person.class, secondPerson.getId() ) ) - // Null values don't get persisted - .invoke( foundPerson -> assertPhones( context, foundPerson, "567" ) ) + test( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session.persist( secondPerson ) ) + // Check new person collection + .chain( () -> openMutinySession().find( Person.class, secondPerson.getId() ) ) + // Null values don't get persisted + .invoke( foundPerson -> assertPhones( context, foundPerson, "567" ) ) ); } @Test public void setCollectionToNullWithStageAPI(TestContext context) { - Stage.Session session = openSession(); - - test( context, - session.find( Person.class, thePerson.getId() ) - .thenAccept( found -> { - context.assertFalse( found.getPhones().isEmpty() ); - found.setPhones( null ); - } ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) - .thenAccept( foundPerson -> assertPhones( context, foundPerson ) ) + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) + .thenAccept( found -> { + context.assertFalse( found.getPhones().isEmpty() ); + found.setPhones( null ); + } ) + ) + .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) + .thenAccept( foundPerson -> assertPhones( context, foundPerson ) ) ); } @Test public void setCollectionToNullWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - - test( context, - session.find( Person.class, thePerson.getId() ) - .invoke( found -> { - context.assertFalse( found.getPhones().isEmpty() ); - found.setPhones( null ); - } ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( foundPerson -> assertPhones( context, foundPerson ) ) + test( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) + .invoke( found -> { + context.assertFalse( found.getPhones().isEmpty() ); + found.setPhones( null ); + } ) + ) + .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) + .invoke( foundPerson -> assertPhones( context, foundPerson ) ) ); } @@ -596,21 +503,9 @@ private Uni> selectFromPhonesWithMutiny(Person person) { .getResultList(); } - /** - * Utility method to check the content of the collection of elements. - * It sorts the expected and actual phones before comparing. - */ private static void assertPhones(TestContext context, Person person, String... expectedPhones) { context.assertNotNull( person ); - String[] sortedExpected = Arrays.stream( expectedPhones ).sorted() - .sorted( String.CASE_INSENSITIVE_ORDER ) - .collect( Collectors.toList() ) - .toArray( new String[expectedPhones.length] ); - List sortedActual = person.getPhones().stream() - .sorted( String.CASE_INSENSITIVE_ORDER ) - .collect( Collectors.toList() ); - Assertions.assertThat( sortedActual ) - .containsExactly( sortedExpected ); + assertThat( person.getPhones() ).containsExactlyInAnyOrder( expectedPhones ); } @Entity(name = "Person") diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeMapTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeMapTest.java index 088d8c1e6..c366a6668 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeMapTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeMapTest.java @@ -20,6 +20,7 @@ import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.stage.Stage; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -59,6 +60,11 @@ public void populateDb(TestContext context) { test( context, session.persist( thePerson ).call( session::flush ) ); } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); + } + @Test public void persistWithMutinyAPI(TestContext context) { Mutiny.Session session = openMutinySession(); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeSetTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeSetTest.java index 85a593dda..e49e68431 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeSetTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForBasicTypeSetTest.java @@ -23,6 +23,7 @@ import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.stage.Stage; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -64,6 +65,11 @@ public void populateDb(TestContext context) { test( context, session.persist( thePerson ).call( session::flush ) ); } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); + } + @Test public void persistWithMutinyAPI(TestContext context) { Mutiny.Session session = openMutinySession(); @@ -159,32 +165,27 @@ public void removeOneElementWithStageAPI(TestContext context) { @Test public void removeOneElementWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) // Remove one element from the collection - .invoke( foundPerson -> foundPerson.getPhones().remove( "111-111-1111" ) ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( updatedPerson -> assertPhones( context, updatedPerson, "999-999-9999", "123-456-7890" ) ) + .invoke( foundPerson -> foundPerson.getPhones().remove( "111-111-1111" ) ) ) + .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) + .invoke( updatedPerson -> assertPhones( context, updatedPerson, "999-999-9999", "123-456-7890" ) ) ); } @Test public void clearCollectionOfElementsWithStageAPI(TestContext context){ - Stage.Session session = openSession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .thenAccept( foundPerson -> { context.assertFalse( foundPerson.getPhones().isEmpty() ); foundPerson.getPhones().clear(); - } ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) + } ) ) + .thenCompose( v -> openSession() + .find( Person.class, thePerson.getId() ) .thenAccept( changedPerson -> context.assertTrue( changedPerson.getPhones().isEmpty() ) ) ) ); @@ -192,54 +193,45 @@ public void clearCollectionOfElementsWithStageAPI(TestContext context){ @Test public void clearCollectionOfElementsWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - - test( - context, - session.find( Person.class, thePerson.getId() ) + test( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .invoke( foundPerson -> { context.assertFalse( foundPerson.getPhones().isEmpty() ); foundPerson.getPhones().clear(); - } ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( changedPerson -> context.assertTrue( changedPerson.getPhones().isEmpty() ) ) + } ) ) + .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) + .invoke( changedPerson -> context.assertTrue( changedPerson.getPhones().isEmpty() ) ) ); } @Test - public void removeAndAddElementWithStageAPI(TestContext context){ - Stage.Session session = openSession(); - - test ( - context, - session.find( Person.class, thePerson.getId()) + public void removeAndAddElementWithStageAPI(TestContext context) { + test( context, getSessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .thenAccept( foundPerson -> { context.assertNotNull( foundPerson ); foundPerson.getPhones().remove( "111-111-1111" ); foundPerson.getPhones().add( "000" ); - } ) - .thenCompose( v -> session.flush() ) - .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) - .thenAccept( changedPerson -> assertPhones( context, changedPerson, "999-999-9999", "123-456-7890", "000" ) ) + } ) ) + .thenCompose( v -> openSession().find( Person.class, thePerson.getId() ) ) + .thenAccept( changedPerson -> assertPhones( context, changedPerson, "999-999-9999", "123-456-7890", "000" ) ) ); } @Test public void removeAndAddElementWithMutinyAPI(TestContext context){ - Mutiny.Session session = openMutinySession(); - - test ( - context, - session.find( Person.class, thePerson.getId()) + test ( context, getMutinySessionFactory() + .withTransaction( (session, transaction) -> session + .find( Person.class, thePerson.getId() ) .invoke( foundPerson -> { context.assertNotNull( foundPerson ); foundPerson.getPhones().remove( "111-111-1111" ); foundPerson.getPhones().add( "000" ); - } ) - .call( session::flush ) - .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( person -> assertPhones( context, person, "999-999-9999", "123-456-7890", "000" ) ) + } ) ) + .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) + .invoke( person -> assertPhones( context, person, "999-999-9999", "123-456-7890", "000" ) ) ); } diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddableEntityTypeMapTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddableEntityTypeMapTest.java index 3e0d7353a..e0d1401bd 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddableEntityTypeMapTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddableEntityTypeMapTest.java @@ -21,6 +21,7 @@ import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.stage.Stage; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -47,6 +48,11 @@ public void populateDb(TestContext context) { test( context, session.persist( thePerson ).call( session::flush ) ); } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); + } + @Test public void persistWithMutinyAPI(TestContext context) { Mutiny.Session session = openMutinySession(); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddableTypeListTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddableTypeListTest.java index 1cce78f65..31940ff3f 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddableTypeListTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddableTypeListTest.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.CompletionStage; +import java.util.stream.Collectors; import javax.persistence.ElementCollection; import javax.persistence.Embeddable; import javax.persistence.Entity; @@ -20,12 +21,15 @@ import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.stage.Stage; +import org.junit.After; import org.junit.Before; import org.junit.Test; import io.smallrye.mutiny.Uni; import io.vertx.ext.unit.TestContext; +import static org.assertj.core.api.Assertions.assertThat; + /** * Tests @{@link ElementCollection} on a {@link java.util.Set} of basic types. *

@@ -71,6 +75,11 @@ public void populateDb(TestContext context) { ); } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); + } + @Test public void persistWithMutinyAPI(TestContext context) { Mutiny.Session session = openMutinySession(); @@ -202,8 +211,6 @@ public void updateCollectionWithDuplicatesWithStageAPI(TestContext context) { @Test public void updateCollectionWithDuplicatesWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - List phones = new ArrayList<>(); phones.add( new Phone( "000" ) ); phones.add( new Phone( "000" ) ); @@ -212,22 +219,19 @@ public void updateCollectionWithDuplicatesWithMutinyAPI(TestContext context) { Person thomas = new Person( 47, "Thomas Reaper", phones ); - test( - context, - session.persist( thomas ) - .call( session::flush ) - .chain( () -> { - Mutiny.Session newSession = openMutinySession(); - return newSession.find( Person.class, thomas.getId() ) - // Change a couple of the elements in the collection - .invoke( found -> { - found.getPhones().set( 1, new Phone( "47" ) ); - found.getPhones().set( 3, new Phone( "47" ) ); - } ) - .call( newSession::flush ) - .chain( () -> openMutinySession().find( Person.class, thomas.getId() ) ) - .invoke( found -> assertPhones( context, found, "000", "47", "000", "47" ) ); + test( context, getMutinySessionFactory() + .withTransaction( (session, tx) -> session.persist( thomas ) ) + .chain( () -> getMutinySessionFactory().withSession( session -> session + .find( Person.class, thomas.getId() ) + // Change a couple of the elements in the collection + .invoke( found -> { + found.getPhones().set( 1, new Phone( "47" ) ); + found.getPhones().set( 3, new Phone( "47" ) ); } ) + .call( session::flush ) + .chain( () -> openMutinySession().find( Person.class, thomas.getId() ) ) + .invoke( found -> assertPhones( context, found, "000", "47", "000", "47" ) ) + ) ) ); } @@ -297,22 +301,16 @@ public void deleteElementsFromCollectionWithDuplicatesWithMutinyAPI(TestContext @Test public void addOneElementWithMutinyAPI(TestContext context) { - Mutiny.Session session = openMutinySession(); - test( context, - session.find( Person.class, thePerson.getId() ) - // add one element to the collection - .invoke( foundPerson -> foundPerson.getPhones().add( new Phone("000" ) ) ) - .call( session::flush ) + getMutinySessionFactory() + .withTransaction( (session, tx) -> session + .find( Person.class, thePerson.getId() ) + // add one element to the collection + .invoke( foundPerson -> foundPerson.getPhones().add( new Phone( "000" ) ) ) ) // Check new person collection .chain( () -> openMutinySession().find( Person.class, thePerson.getId() ) ) - .invoke( updatedPerson -> - assertPhones( - context, - updatedPerson, - "999-999-9999", "111-111-1111", "000" - ) ) + .invoke( updatedPerson -> assertPhones( context, updatedPerson, "999-999-9999", "111-111-1111", "000" ) ) ); } @@ -549,11 +547,7 @@ public void persistAnotherPersonWithMutinyAPI(TestContext context) { ) ); - Mutiny.Session session = openMutinySession(); - - test( context, - session.persist( secondPerson ) - .call( session::flush ) + test( context, getMutinySessionFactory().withTransaction( (session, tx) -> session.persist( secondPerson )) // Check new person collection .chain( () -> openMutinySession().find( Person.class, secondPerson.getId() ) ) .invoke( foundPerson -> assertPhones( context, foundPerson, "222-222-2222", "333-333-3333", "444-444-4444" ) ) @@ -683,10 +677,11 @@ private Uni> selectFromPhonesWithMutiny(Person person) { private static void assertPhones(TestContext context, Person person, String... phones) { context.assertNotNull( person ); - context.assertEquals( phones.length, person.getPhones().size() ); - for (int i=0; i personPhones = person.getPhones() + .stream().map( phone -> phone.getNumber() ).collect( Collectors.toList() ); + + assertThat( personPhones ).containsExactlyInAnyOrder( phones ); } @Entity(name = "Person") diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddedEmbeddableMapTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddedEmbeddableMapTest.java index e6ca18ca9..bca00c2f3 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddedEmbeddableMapTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddedEmbeddableMapTest.java @@ -21,6 +21,7 @@ import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.stage.Stage; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -48,6 +49,11 @@ public void populateDb(TestContext context) { test( context, session.persist( thePerson ).call( session::flush ) ); } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); + } + @Test public void persistWithMutinyAPI(TestContext context) { Mutiny.Session session = openMutinySession(); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddedEmbeddableTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddedEmbeddableTest.java index ce71da015..3ffefee7f 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddedEmbeddableTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerElementCollectionForEmbeddedEmbeddableTest.java @@ -21,6 +21,7 @@ import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.stage.Stage; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -71,6 +72,11 @@ public void populateDb(TestContext context) { ); } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); + } + @Test public void persistWithMutinyAPI(TestContext context) { Mutiny.Session session = openMutinySession(); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerManyToOneAssociationTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerManyToOneAssociationTest.java index f521af3a9..c696fd34a 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerManyToOneAssociationTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerManyToOneAssociationTest.java @@ -7,6 +7,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.*; @@ -25,6 +27,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( Book.class, Author.class ) ); + } + @Test public void persistOneBook(TestContext context) { final Book book = new Book( 6, "The Boy, The Mole, The Fox and The Horse" ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOneToManyAssociationTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOneToManyAssociationTest.java index 611c7b0a4..d2f8f41c6 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOneToManyAssociationTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOneToManyAssociationTest.java @@ -5,7 +5,6 @@ */ package org.hibernate.reactive; -import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; import org.junit.Test; @@ -14,6 +13,10 @@ import java.util.List; import java.util.Objects; +import org.junit.After; + +import io.vertx.ext.unit.TestContext; + import static org.hibernate.reactive.util.impl.CompletionStages.completedFuture; import static org.hibernate.reactive.util.impl.CompletionStages.voidFuture; @@ -25,6 +28,11 @@ protected Configuration constructConfiguration() { configuration.addAnnotatedClass( Author.class ); return configuration; } + + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( Author.class, Book.class ) ); + } // // private CompletionStage populateDB(Book... books) { // StringBuilder authorQueryBuilder = new StringBuilder(); @@ -89,13 +97,13 @@ public void getBookWithAuthors(TestContext context) { test( context, - completedFuture( getSessionFactory().openStatelessSession() ) + completedFuture( openStatelessSession() ) .thenCompose( s -> voidFuture() .thenCompose( v -> s.insert(goodOmens) ) .thenCompose( v -> s.insert(neilGaiman) ) .thenCompose( v -> s.insert(terryPratchett) ) ) - .thenApply( v -> getSessionFactory().openStatelessSession() ) + .thenApply( v -> openStatelessSession() ) .thenCompose( s -> s.get( Book.class, goodOmens.getId() ) ) .thenAccept( optionalBook -> { context.assertNotNull( optionalBook ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOneToOneAssociationTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOneToOneAssociationTest.java index 2ee2501d4..e9bb36de0 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOneToOneAssociationTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOneToOneAssociationTest.java @@ -7,6 +7,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.*; @@ -24,6 +26,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( Book.class, Author.class ) ); + } + @Test public void testPersist(TestContext context) { final Book mostPopularBook = new Book( 5, "The Boy, The Mole, The Fox and The Horse" ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOrderedElementCollectionForEmbeddableTypeListTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOrderedElementCollectionForEmbeddableTypeListTest.java index 0f19c6076..c7c8bf506 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOrderedElementCollectionForEmbeddableTypeListTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerOrderedElementCollectionForEmbeddableTypeListTest.java @@ -10,6 +10,8 @@ import org.hibernate.cfg.Configuration; import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.stage.Stage; + +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -70,6 +72,11 @@ public void populateDb(TestContext context) { ); } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); + } + @Test public void persistWithMutinyAPI(TestContext context) { Mutiny.Session session = openMutinySession(); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerTest.java index d12a4deae..acc4ba27d 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EagerTest.java @@ -10,6 +10,8 @@ import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.CascadeType; @@ -46,6 +48,13 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, getSessionFactory() + .withTransaction( (s, t) -> s.createQuery( "delete from Element" ).executeUpdate() + .thenCompose( v -> s.createQuery( "delete from Node" ).executeUpdate() ) ) ); + } + @Test public void testEagerCollectionFetch(TestContext context) { diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EmptyCompositeCollectionKeyTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EmptyCompositeCollectionKeyTest.java index 4cc4c1916..6c62a4d88 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EmptyCompositeCollectionKeyTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/EmptyCompositeCollectionKeyTest.java @@ -22,6 +22,7 @@ import org.hibernate.reactive.stage.Stage; import org.hibernate.reactive.testing.DatabaseSelectionRule; +import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -40,6 +41,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Family" ) ); + } + @Test public void testGetEntityWithEmptyChildrenCollection(TestContext context) { /* CASE 1: Family has Parent + child with null names + NULL relatives */ diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/FetchModeSubselectEagerTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/FetchModeSubselectEagerTest.java index f807d0219..af6937242 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/FetchModeSubselectEagerTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/FetchModeSubselectEagerTest.java @@ -10,6 +10,8 @@ import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.*; @@ -30,6 +32,13 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, getSessionFactory() + .withTransaction( (s, t) -> s.createQuery( "delete from Element" ).executeUpdate() + .thenCompose( v -> s.createQuery( "delete from Node" ).executeUpdate() ) ) ); + } + @Test public void testEagerCollectionFetch(TestContext context) { diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/FilterTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/FilterTest.java index c52dcd4ca..424b83694 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/FilterTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/FilterTest.java @@ -8,6 +8,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.annotations.Filter; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.*; @@ -30,6 +32,14 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Element" ) + .thenCompose( v -> getSessionFactory() + .withTransaction( (s, t) -> s + .createQuery( "delete from Node" ).executeUpdate() ) ) ); + } + @Test public void testFilter(TestContext context) { diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertyJoinedTableTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertyJoinedTableTest.java index effa79f0e..3cacd5d28 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertyJoinedTableTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertyJoinedTableTest.java @@ -23,6 +23,7 @@ import org.hibernate.cfg.Configuration; import org.hibernate.reactive.testing.DatabaseSelectionRule; +import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -50,6 +51,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "GeneratedWithIdentity", "GeneratedRegular" ) ); + } + @Test public void testWithIdentity(TestContext context) { final GeneratedWithIdentity davide = new GeneratedWithIdentity( "Davide", "D'Alto" ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertySingleTableTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertySingleTableTest.java index 48a857bcb..f4178f66e 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertySingleTableTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertySingleTableTest.java @@ -22,6 +22,7 @@ import org.hibernate.cfg.Configuration; import org.hibernate.reactive.testing.DatabaseSelectionRule; +import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -48,6 +49,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( GeneratedWithIdentity.class, GeneratedRegular.class ) ); + } + @Test public void testWithIdentity(TestContext context) { final GeneratedWithIdentity davide = new GeneratedWithIdentity( "Davide", "D'Alto" ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertyUnionSubclassesTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertyUnionSubclassesTest.java index b1d66583b..58f9b554c 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertyUnionSubclassesTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/GeneratedPropertyUnionSubclassesTest.java @@ -23,6 +23,7 @@ import org.hibernate.cfg.Configuration; import org.hibernate.reactive.testing.DatabaseSelectionRule; +import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -52,6 +53,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( GeneratedRegular.class ) ); + } + @Test public void testRegularEntity(TestContext context) { final GeneratedRegular davide = new GeneratedRegular( "Davide", "D'Alto" ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentifierGenerationTypeTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentifierGenerationTypeTest.java index 2a279b55e..2053993be 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentifierGenerationTypeTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentifierGenerationTypeTest.java @@ -16,6 +16,7 @@ import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.stage.Stage; +import org.junit.After; import org.junit.Test; import io.vertx.ext.unit.TestContext; @@ -36,6 +37,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( LongEntity.class, IntegerEntity.class, ShortEntity.class ) ); + } + /* * Stage API tests */ diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentityGeneratorTypeForCockroachDBTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentityGeneratorTypeForCockroachDBTest.java index 90176adaa..0195e5afa 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentityGeneratorTypeForCockroachDBTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentityGeneratorTypeForCockroachDBTest.java @@ -9,7 +9,6 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.PersistenceException; import javax.persistence.Table; import org.hibernate.cfg.AvailableSettings; @@ -69,7 +68,7 @@ public void longIdentityType(TestContext context) { LongTypeEntity entity = new LongTypeEntity(); test( context, getMutinySessionFactory() - .withSession( s -> s.persist( entity ).call( s::flush ) ) + .withTransaction( (s, tx) -> s.persist( entity ) ) .invoke( () -> { context.assertNotNull( entity ); context.assertTrue( entity.id > 0 ); @@ -79,23 +78,21 @@ public void longIdentityType(TestContext context) { @Test public void integerIdentityType(TestContext context) { - thrown.expect( PersistenceException.class ); thrown.expectMessage( "too big" ); thrown.expectMessage( "Integer" ); test( context, getMutinySessionFactory() - .withSession( s -> s.persist( new IntegerTypeEntity() ).call( s::flush ) ) + .withTransaction( (s, tx) -> s.persist( new IntegerTypeEntity() ) ) ); } @Test public void shortIdentityType(TestContext context) { - thrown.expect( PersistenceException.class ); thrown.expectMessage( "too big" ); thrown.expectMessage( "Short" ); test( context, getMutinySessionFactory() - .withSession( s -> s.persist( new ShortTypeEntity() ).call( s::flush ) ) + .withTransaction( (s, tx) -> s.persist( new ShortTypeEntity() ) ) ); } diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentityGeneratorTypeTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentityGeneratorTypeTest.java index 44c00400a..df4e7dbe2 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentityGeneratorTypeTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/IdentityGeneratorTypeTest.java @@ -15,6 +15,7 @@ import org.hibernate.cfg.Configuration; import org.hibernate.reactive.testing.DatabaseSelectionRule; +import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -62,6 +63,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( IntegerTypeEntity.class, ShortTypeEntity.class, LongTypeEntity.class ) ); + } + private > void assertType( TestContext context, Class entityClass, diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/JoinedSubclassIdentityTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/JoinedSubclassIdentityTest.java index 9e51a2a13..c8f12752b 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/JoinedSubclassIdentityTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/JoinedSubclassIdentityTest.java @@ -7,6 +7,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.Entity; @@ -26,6 +28,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "GeneratedWithIdentityParent", "GeneratedWithIdentity" ) ); + } + @Test public void testParent(TestContext context) { test(context, getMutinySessionFactory().withSession( s -> s.persist( new GeneratedWithIdentityParent() ) diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/JoinedSubclassInheritanceTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/JoinedSubclassInheritanceTest.java index ccc4a3517..44efa665c 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/JoinedSubclassInheritanceTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/JoinedSubclassInheritanceTest.java @@ -7,6 +7,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.*; @@ -26,6 +28,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Book", "Author", "SpellBook" ) ); + } + @Test public void testRootClassViaAssociation(TestContext context) { final Book book = new Book( 6, "The Boy, The Mole, The Fox and The Horse", new Date()); @@ -254,7 +261,7 @@ public int hashCode() { } } - @Entity + @Entity(name = "Author") @Table(name = "Author") public static class Author { diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyManyToOneAssociationTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyManyToOneAssociationTest.java index 1fb3afcc1..9358ff43a 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyManyToOneAssociationTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyManyToOneAssociationTest.java @@ -9,6 +9,8 @@ import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.FetchProfile; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.DiscriminatorValue; @@ -35,6 +37,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( Book.class, Author.class ) ); + } + @Test public void fetchProfileWithOneAuthor(TestContext context) { final Book book = new Book( 6, "The Boy, The Mole, The Fox and The Horse" ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyOneToManyAssociationWithFetchTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyOneToManyAssociationWithFetchTest.java index aec1bbdd1..c6ee7f99f 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyOneToManyAssociationWithFetchTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyOneToManyAssociationWithFetchTest.java @@ -11,6 +11,8 @@ import org.hibernate.annotations.FetchProfile; import org.hibernate.cfg.Configuration; import org.hibernate.reactive.stage.Stage; + +import org.junit.After; import org.junit.Test; import javax.persistence.Entity; @@ -37,6 +39,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Writer", "Tome" ) ); + } + @Test public void findBookWithFetchAuthors(TestContext context) { final Book goodOmens = new Book(7242353, "Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch"); @@ -239,12 +246,12 @@ public void getBookWithFetchAuthors(TestContext context) { test( context, - completedFuture( getSessionFactory().openStatelessSession() ) + completedFuture( openStatelessSession() ) .thenCompose(s -> s.insert(goodOmens) .thenCompose(v -> s.insert(neilGaiman)) .thenCompose(v -> s.insert(terryPratchett)) ) - .thenApply( v -> getSessionFactory().openStatelessSession() ) + .thenApply( v -> openStatelessSession() ) .thenCompose( s -> s.get(Book.class, goodOmens.getId()) .thenCompose( book -> s.fetch( book.getAuthors() ) @@ -269,7 +276,7 @@ public void getBookWithEntityGrpahAuthors(TestContext context) { test( context, - completedFuture( getSessionFactory().openStatelessSession() ) + completedFuture( openStatelessSession() ) .thenCompose(s -> s.insert(goodOmens) .thenCompose(v -> s.insert(neilGaiman)) .thenCompose(v -> s.insert(terryPratchett)) diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyOrderedElementCollectionForEmbeddableTypeListTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyOrderedElementCollectionForEmbeddableTypeListTest.java index 817884bbe..b918062be 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyOrderedElementCollectionForEmbeddableTypeListTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/LazyOrderedElementCollectionForEmbeddableTypeListTest.java @@ -9,6 +9,8 @@ import org.hibernate.Hibernate; import org.hibernate.cfg.Configuration; import org.hibernate.reactive.stage.Stage; + +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -52,6 +54,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); + } + @Before public void populateDb(TestContext context) { List phones = new ArrayList<>(); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MultipleContextTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MultipleContextTest.java index cfb865545..e21f0dbc9 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MultipleContextTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MultipleContextTest.java @@ -5,30 +5,45 @@ */ package org.hibernate.reactive; -import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletableFuture; import javax.persistence.Entity; import javax.persistence.Id; import org.hibernate.cfg.Configuration; import org.hibernate.reactive.mutiny.Mutiny; import org.hibernate.reactive.stage.Stage; +import org.hibernate.reactive.testing.DatabaseSelectionRule; +import org.junit.Rule; import org.junit.Test; import io.smallrye.mutiny.Uni; import io.vertx.core.Context; import io.vertx.core.Vertx; +import io.vertx.ext.unit.Async; import io.vertx.ext.unit.TestContext; import org.assertj.core.api.Assertions; +import static org.hibernate.reactive.containers.DatabaseConfiguration.DBType.POSTGRESQL; +import static org.hibernate.reactive.testing.DatabaseSelectionRule.runOnlyFor; + /** * It's currently considered an error to share a Session between multiple reactive streams, * so we should detect that condition and throw an exception. + *

+ * WARNING: Because we are running the code to test inside a function, we must create the {@link Async} + * in advance. Otherwise the test will end successfully because the async has not been created yet. + *

*/ public class MultipleContextTest extends BaseReactiveTest { private static final String ERROR_MESSAGE = "Detected use of the reactive Session from a different Thread"; + // These tests will fail before touching the database, so there is no reason + // to run them on all databases + @Rule + public DatabaseSelectionRule rule = runOnlyFor( POSTGRESQL ); + @Override protected Configuration constructConfiguration() { Configuration configuration = super.constructConfiguration(); @@ -37,100 +52,93 @@ protected Configuration constructConfiguration() { } @Test - public void testPersistWithStage(TestContext testContext) throws Exception { + public void testPersistWithStage(TestContext testContext) { + Async async = testContext.async(); Stage.Session session = openSession(); Context testVertxContext = Vertx.currentContext(); // Create a different new context - Vertx vertx = Vertx.vertx(); - Context newContext = vertx.getOrCreateContext(); + Context newContext = Vertx.vertx().getOrCreateContext(); Assertions.assertThat( testVertxContext ).isNotEqualTo( newContext ); // Run test in the new context - newContext.runOnContext( event -> - test( testContext, session - .persist( new Competition( "Cheese Rolling" ) ) - .handle( (v, e) -> { - testContext.assertNotNull( e ); - testContext.assertEquals( CompletionException.class, e.getClass() ); - testContext.assertEquals( IllegalStateException.class, e.getCause().getClass() ); - testContext.assertTrue( e.getMessage().contains( ERROR_MESSAGE ) ); - return null; - } ) ) + newContext.runOnContext( event -> test( async, testContext, session + .persist( new Competition( "Cheese Rolling" ) ) + .thenCompose( v -> session.flush() ) + .handle( (v, e) -> assertExceptionThrown( e ).join() ) ) ); } - @Test - public void testFindWithStage(TestContext testContext) throws Exception { + public void testFindWithStage(TestContext testContext) { + Async async = testContext.async(); Stage.Session session = openSession(); Context testVertxContext = Vertx.currentContext(); // Create a different new context - Vertx vertx = Vertx.vertx(); - Context newContext = vertx.getOrCreateContext(); + Context newContext = Vertx.vertx().getOrCreateContext(); Assertions.assertThat( testVertxContext ).isNotEqualTo( newContext ); // Run test in the new context - newContext.runOnContext( event -> - test( testContext, session - .find( Competition.class, "Chess boxing" ) - .handle( (v, e) -> { - testContext.assertNotNull( e ); - testContext.assertEquals( CompletionException.class, e.getClass() ); - testContext.assertEquals( IllegalStateException.class, e.getCause().getClass() ); - testContext.assertTrue( e.getMessage().contains( ERROR_MESSAGE ) ); - return null; - } ) ) + newContext.runOnContext( event -> test( async, testContext, session + .find( Competition.class, "Chess boxing" ) + .handle( (v, e) -> assertExceptionThrown( e ).join() ) ) ); } @Test - public void testOnPersistWithMutiny(TestContext testContext) throws Exception { + public void testOnPersistWithMutiny(TestContext testContext) { + Async async = testContext.async(); Mutiny.Session session = openMutinySession(); Context testVertxContext = Vertx.currentContext(); // Create a different new context - Vertx vertx = Vertx.vertx(); - Context newContext = vertx.getOrCreateContext(); + Context newContext = Vertx.vertx().getOrCreateContext(); Assertions.assertThat( testVertxContext ).isNotEqualTo( newContext ); // Run test in the new context - newContext.runOnContext( event -> - test( testContext, session - .persist( new Competition( "Cheese Rolling" ) ) - .onItem().invoke( v -> testContext.fail( "We were expecting an exception" ) ) - .onFailure().recoverWithUni( e -> { - testContext.assertEquals( IllegalStateException.class, e.getClass() ); - testContext.assertTrue( e.getMessage().contains( ERROR_MESSAGE ) ); - return Uni.createFrom().voidItem(); - } ) ) + newContext.runOnContext( event -> test( async, testContext, session + .persist( new Competition( "Cheese Rolling" ) ) + .call( session::flush ) + .onItemOrFailure() + .transformToUni( (unused, e) -> Uni.createFrom().completionStage( assertExceptionThrown( e ) ) ) ) ); } @Test - public void testFindWithMutiny(TestContext testContext) throws Exception { + public void testFindWithMutiny(TestContext testContext) { + Async async = testContext.async(); Mutiny.Session session = openMutinySession(); Context testVertxContext = Vertx.currentContext(); // Create a different new context - Vertx vertx = Vertx.vertx(); - Context newContext = vertx.getOrCreateContext(); + Context newContext = Vertx.vertx().getOrCreateContext(); Assertions.assertThat( testVertxContext ).isNotEqualTo( newContext ); // Run test in the new context - newContext.runOnContext(event -> - test( testContext, session - .find( Competition.class, "Chess boxing" ) - .onItem().invoke( v -> testContext.fail( "We were expecting an exception" ) ) - .onFailure().recoverWithUni( e -> { - testContext.assertEquals( IllegalStateException.class, e.getClass() ); - testContext.assertTrue( e.getMessage().contains( ERROR_MESSAGE ) ); - return Uni.createFrom().nullItem(); - } ) ) + newContext.runOnContext( event -> test( async, testContext, session + .find( Competition.class, "Chess boxing" ) + .onItemOrFailure() + .transformToUni( (unused, e) -> Uni.createFrom().completionStage( assertExceptionThrown( e ) ) ) ) ); } + // Check that at least one exception has the expected message + private static CompletableFuture assertExceptionThrown(Throwable e) { + CompletableFuture result = new CompletableFuture<>(); + Throwable t = e; + while ( t != null ) { + if ( t.getClass().equals( IllegalStateException.class ) + && t.getMessage().contains( ERROR_MESSAGE ) ) { + result.complete( null ); + return result; + } + t = t.getCause(); + } + result.completeExceptionally( new AssertionError( "Expected exception not thrown. Exception thrown: " + e ) ); + return result; + } + @Entity static class Competition { @Id diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MutinySessionTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MutinySessionTest.java index 40bc5d2dc..030c69754 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MutinySessionTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MutinySessionTest.java @@ -9,6 +9,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.LockMode; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.Entity; @@ -28,6 +30,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "GuineaPig" ) ); + } + private Uni populateDB() { return getMutinySessionFactory() .withSession( diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/OrderedEmbeddableCollectionTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/OrderedEmbeddableCollectionTest.java index bd9431df5..b93922597 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/OrderedEmbeddableCollectionTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/OrderedEmbeddableCollectionTest.java @@ -22,6 +22,7 @@ import org.hibernate.cfg.Configuration; import org.hibernate.reactive.testing.DatabaseSelectionRule; +import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -38,11 +39,15 @@ public class OrderedEmbeddableCollectionTest extends BaseReactiveTest { @Override protected Configuration constructConfiguration() { Configuration configuration = super.constructConfiguration(); - configuration.addAnnotatedClass( Book.class ); configuration.addAnnotatedClass( Author.class ); return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Author" ) ); + } + @Test public void test(TestContext context) { Book book1 = new Book("Feersum Endjinn"); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/QueryTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/QueryTest.java index 88989405b..f38d525ba 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/QueryTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/QueryTest.java @@ -8,6 +8,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; import org.hibernate.reactive.containers.DatabaseConfiguration; + +import org.junit.After; import org.junit.Test; import javax.persistence.ColumnResult; @@ -49,6 +51,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDB(TestContext context) { + test( context, deleteEntities( "Book", "Author" ) ); + } + @Test public void testCriteriaEntityQuery(TestContext context) { Author author1 = new Author("Iain M. Banks"); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveSessionTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveSessionTest.java index 8463a0ed9..94f84cae2 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveSessionTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveSessionTest.java @@ -11,6 +11,8 @@ import org.hibernate.cfg.Configuration; import org.hibernate.reactive.common.AffectedEntities; import org.hibernate.reactive.stage.Stage; + +import org.junit.After; import org.junit.Test; import javax.persistence.Entity; @@ -24,7 +26,6 @@ import static org.hibernate.reactive.util.impl.CompletionStages.completedFuture; import static org.hibernate.reactive.util.impl.CompletionStages.voidFuture; - public class ReactiveSessionTest extends BaseReactiveTest { @Override @@ -37,26 +38,12 @@ protected Configuration constructConfiguration() { private CompletionStage populateDB() { return getSessionFactory() - .withSession( - session -> session.persist( new GuineaPig(5, "Aloi") ) - .thenCompose( v -> session.flush() ) - ); + .withTransaction( (s, tx) -> s.persist( new GuineaPig( 5, "Aloi" ) ) ); } - private CompletionStage cleanDB() { - return getSessionFactory() - .withSession( session -> session.createQuery( "delete GuineaPig" ).executeUpdate() ); - } - - public void after(TestContext context) { - test( context, - cleanDB() - .whenComplete( (res, err) -> { - // in case cleanDB() fails we - // still have to close the factory - super.after( context ); - } ) - ); + @After + public void cleanDB(TestContext context) { + test( context, deleteEntities( "GuineaPig" ) ); } private CompletionStage selectNameFromId(Integer id) { @@ -94,7 +81,6 @@ public void reactiveFind(TestContext context) { session.detach( actualPig ); context.assertFalse( session.contains( actualPig ) ); } ) - .whenComplete( (v, err) -> session.close() ) ) ); } @@ -121,42 +107,38 @@ public void reactivePersistFindDelete(TestContext context) { .thenCompose( v -> session.find( GuineaPig.class, guineaPig.getId() ) ) .thenCompose( pig -> session.remove(pig) ) .thenCompose( v -> session.flush() ) - .whenComplete( (v, err) -> session.close() ) ); } @Test public void reactiveFindWithLock(TestContext context) { final GuineaPig expectedPig = new GuineaPig( 5, "Aloi" ); - test( - context, - populateDB() - .thenApply( v -> openSession() ) - .thenCompose( session -> session.find( GuineaPig.class, expectedPig.getId(), LockMode.PESSIMISTIC_WRITE ) - .thenAccept( actualPig -> { - assertThatPigsAreEqual( context, expectedPig, actualPig ); - context.assertEquals( session.getLockMode( actualPig ), LockMode.PESSIMISTIC_WRITE ); - } ) - .whenComplete( (v, err) -> session.close() ) - ) + + test( context, populateDB().thenCompose( v -> getSessionFactory() + .withTransaction( (session, tx) -> session + .find( GuineaPig.class, expectedPig.getId(), LockMode.PESSIMISTIC_WRITE ) + .thenAccept( actualPig -> { + assertThatPigsAreEqual( context, expectedPig, actualPig ); + context.assertEquals( session.getLockMode( actualPig ), LockMode.PESSIMISTIC_WRITE ); + } ) + ) ) ); } @Test public void reactiveFindRefreshWithLock(TestContext context) { final GuineaPig expectedPig = new GuineaPig( 5, "Aloi" ); - test( - context, - populateDB() - .thenApply( v -> openSession() ) - .thenCompose( session -> session.find( GuineaPig.class, expectedPig.getId() ) - .thenCompose( pig -> session.refresh(pig, LockMode.PESSIMISTIC_WRITE).thenApply( v -> pig ) ) - .thenAccept( actualPig -> { - assertThatPigsAreEqual( context, expectedPig, actualPig ); - context.assertEquals( session.getLockMode( actualPig ), LockMode.PESSIMISTIC_WRITE ); - } ) - .whenComplete( (v, err) -> session.close() ) - ) + test( context, populateDB() + .thenCompose( v -> getSessionFactory() + .withTransaction( (session, tx) -> session + .find( GuineaPig.class, expectedPig.getId() ) + .thenCompose( pig -> session.refresh( pig, LockMode.PESSIMISTIC_WRITE ) + .thenAccept( vv -> { + assertThatPigsAreEqual( context, expectedPig, pig ); + context.assertEquals(session.getLockMode( pig ), LockMode.PESSIMISTIC_WRITE ); + } ) + ) + ) ) ); } @@ -192,7 +174,6 @@ public void reactiveFindReadOnlyRefreshWithLock(TestContext context) { context.assertEquals(false, session.isReadOnly(pig)); } ); } ) - .whenComplete( (v, err) -> session.close() ) ) ); } @@ -200,37 +181,37 @@ public void reactiveFindReadOnlyRefreshWithLock(TestContext context) { @Test public void reactiveFindThenUpgradeLock(TestContext context) { final GuineaPig expectedPig = new GuineaPig( 5, "Aloi" ); - test( - context, - populateDB() - .thenApply( v -> openSession() ) - .thenCompose( session -> session.find( GuineaPig.class, expectedPig.getId() ) - .thenCompose( pig -> session.lock(pig, LockMode.PESSIMISTIC_READ).thenApply( v -> pig ) ) - .thenAccept( actualPig -> { - assertThatPigsAreEqual( context, expectedPig, actualPig ); - context.assertEquals( session.getLockMode( actualPig ), LockMode.PESSIMISTIC_READ ); - } ) - .whenComplete( (v, err) -> session.close() ) + test( context, populateDB() + .thenCompose( unused -> getSessionFactory() + .withTransaction( (session, tx) -> session + .find( GuineaPig.class, expectedPig.getId() ) + .thenCompose( pig -> session + .lock( pig, LockMode.PESSIMISTIC_READ ) + .thenAccept( v -> { + assertThatPigsAreEqual( context, expectedPig, pig ); + context.assertEquals( session.getLockMode( pig ), LockMode.PESSIMISTIC_READ ); + } ) + ) ) + ) ); } @Test public void reactiveFindThenWriteLock(TestContext context) { final GuineaPig expectedPig = new GuineaPig( 5, "Aloi" ); - test( - context, - populateDB() - .thenApply( v -> openSession() ) - .thenCompose( session -> session.find( GuineaPig.class, expectedPig.getId() ) - .thenCompose( pig -> session.lock(pig, LockMode.PESSIMISTIC_WRITE).thenApply( v -> pig ) ) - .thenAccept( actualPig -> { - assertThatPigsAreEqual( context, expectedPig, actualPig ); - context.assertEquals( session.getLockMode( actualPig ), LockMode.PESSIMISTIC_WRITE ); - context.assertEquals( actualPig.version, 0 ); + test( context, populateDB().thenCompose( v -> getSessionFactory() + .withTransaction( (session, tx) -> session + .find( GuineaPig.class, expectedPig.getId() ) + .thenCompose( pig -> session + .lock( pig, LockMode.PESSIMISTIC_WRITE ) + .thenAccept( vv -> { + assertThatPigsAreEqual( context, expectedPig, pig ); + context.assertEquals( session.getLockMode( pig ), LockMode.PESSIMISTIC_WRITE ); + context.assertEquals( pig.version, 0 ); } ) - .whenComplete( (v, err) -> session.close() ) ) + ) ) ); } @@ -250,7 +231,6 @@ public void reactiveFindThenForceLock(TestContext context) { } ) .thenCompose( v -> session.createQuery("select version from GuineaPig").getSingleResult() ) .thenAccept( version -> context.assertEquals(1, version) ) - .whenComplete( (v, err) -> session.close() ) ) .thenApply( v -> openSession() ) .thenCompose( session -> session.find( GuineaPig.class, expectedPig.getId() ) @@ -262,7 +242,6 @@ public void reactiveFindThenForceLock(TestContext context) { } ) .thenCompose( v -> session.createQuery("select version from GuineaPig").getSingleResult() ) .thenAccept( version -> context.assertEquals(2, version) ) - .whenComplete( (v, err) -> session.close() ) ) ); } diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveStatelessSessionTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveStatelessSessionTest.java index 5f8d50fb9..9bff9c078 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveStatelessSessionTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveStatelessSessionTest.java @@ -8,6 +8,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; import org.hibernate.reactive.stage.Stage; + +import org.junit.After; import org.junit.Test; import javax.persistence.*; @@ -28,10 +30,15 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "GuineaPig" ) ); + } + @Test public void testStatelessSession(TestContext context) { GuineaPig pig = new GuineaPig("Aloi"); - Stage.StatelessSession ss = getSessionFactory().openStatelessSession(); + Stage.StatelessSession ss = openStatelessSession(); test( context, ss.insert(pig) @@ -128,6 +135,7 @@ public void testStatelessSessionCriteria(TestContext context) { .thenAccept( rows -> context.assertEquals(1, rows) ) .thenCompose( v -> ss.createQuery(delete).executeUpdate() ) .thenAccept( rows -> context.assertEquals(1, rows) ) + .thenAccept( v -> ss.close() ) ); } diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SecondaryTableTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SecondaryTableTest.java index e6f07ff4b..8c0859522 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SecondaryTableTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SecondaryTableTest.java @@ -7,6 +7,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.*; @@ -25,6 +27,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( Book.class, Author.class ) ); + } + @Test public void testRootClassViaAssociation(TestContext context) { final Book book = new Book( 6, "The Boy, The Mole, The Fox and The Horse", new Date(), false); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SingleTableInheritanceTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SingleTableInheritanceTest.java index e31dff45e..994d690aa 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SingleTableInheritanceTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SingleTableInheritanceTest.java @@ -7,6 +7,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.*; @@ -27,6 +29,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Book", "Author", "SpellBook" ) ); + } + @Test public void testMultiLoad(TestContext context) { final Book book1 = new Book( 6, "The Boy, The Mole, The Fox and The Horse", new Date()); @@ -271,7 +278,7 @@ public int hashCode() { } } - @Entity + @Entity(name="Author") @Table(name = Author.TABLE) public static class Author { diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SubselectElementCollectionForEmbeddableTypeListTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SubselectElementCollectionForEmbeddableTypeListTest.java index 79e99310c..10f008596 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SubselectElementCollectionForEmbeddableTypeListTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SubselectElementCollectionForEmbeddableTypeListTest.java @@ -11,6 +11,8 @@ import org.hibernate.annotations.FetchMode; import org.hibernate.cfg.Configuration; import org.hibernate.reactive.stage.Stage; + +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -73,6 +75,11 @@ public void populateDb(TestContext context) { ); } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Person" ) ); + } + @Test public void persistWithMutinyAPI(TestContext context) { List phones = new ArrayList<>(); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/UnionSubclassInheritanceTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/UnionSubclassInheritanceTest.java index 6c3dfdc4f..ccddd5e8f 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/UnionSubclassInheritanceTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/UnionSubclassInheritanceTest.java @@ -7,6 +7,8 @@ import io.vertx.ext.unit.TestContext; import org.hibernate.cfg.Configuration; + +import org.junit.After; import org.junit.Test; import javax.persistence.*; @@ -26,6 +28,11 @@ protected Configuration constructConfiguration() { return configuration; } + @After + public void cleanDb(TestContext context) { + test( context, deleteEntities( "Book", "Author", "SpellBook" ) ); + } + @Test public void testRootClassViaAssociation(TestContext context) { final Book book = new Book( 6, "The Boy, The Mole, The Fox and The Horse", new Date()); @@ -254,7 +261,7 @@ public int hashCode() { } } - @Entity + @Entity(name = "Author") @Table(name = "AuthorUS") public static class Author { diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/testing/SessionFactoryManager.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/testing/SessionFactoryManager.java new file mode 100644 index 000000000..8127f7d54 --- /dev/null +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/testing/SessionFactoryManager.java @@ -0,0 +1,53 @@ +/* Hibernate, Relational Persistence for Idiomatic Java + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright: Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.reactive.testing; + +import java.util.function.Supplier; + +import org.hibernate.SessionFactory; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.reactive.pool.ReactiveConnectionPool; + +/** + * Managed the creation of a {@link SessionFactory} that can shared among tests. + */ +public class SessionFactoryManager { + + private SessionFactory sessionFactory; + private ReactiveConnectionPool poolProvider; + + public SessionFactoryManager() { + } + + private boolean needsStart() { + return sessionFactory == null || sessionFactory.isClosed(); + } + + public void start(Supplier supplier) { + if ( needsStart() ) { + sessionFactory = supplier.get(); + poolProvider = sessionFactory + .unwrap( SessionFactoryImplementor.class ) + .getServiceRegistry().getService( ReactiveConnectionPool.class ); + } + } + + public SessionFactory getHibernateSessionFactory() { + return sessionFactory; + } + + public ReactiveConnectionPool getReactiveConnectionPool() { + return poolProvider; + } + + public void stop() { + if ( sessionFactory != null && sessionFactory.isOpen() ) { + sessionFactory.close(); + } + poolProvider = null; + sessionFactory = null; + } +} diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/types/JoinColumnsTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/types/JoinColumnsTest.java index a6d9a643f..fa7c3e398 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/types/JoinColumnsTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/types/JoinColumnsTest.java @@ -31,6 +31,9 @@ import io.smallrye.mutiny.Uni; import io.vertx.ext.unit.TestContext; +import static org.hibernate.reactive.containers.DatabaseConfiguration.DBType.DB2; +import static org.hibernate.reactive.containers.DatabaseConfiguration.dbType; + public class JoinColumnsTest extends BaseReactiveTest { @Override @@ -43,11 +46,14 @@ protected Configuration constructConfiguration() { @After public void cleanDB(TestContext context) { - test( context, getMutinySessionFactory() - .withSession( session -> session - .createQuery( "delete SampleJoinEntity" ).executeUpdate() - .invoke( ignore -> session - .createQuery( "delete SampleEntity" ).executeUpdate() ) ) ); + if ( dbType() == DB2 ) { + // On Db2, the build get stuck if I don't recreate the factory each time + // I don't know why + factoryManager.stop(); + } + else { + test( context, deleteEntities( "SampleJoinEntity", "SampleEntity" ) ); + } } @Test @@ -92,16 +98,16 @@ public void testWithMutiny(TestContext context) { test( context, getMutinySessionFactory() .withTransaction( (session, transaction) -> session.persist( sampleEntity ) ) - .then( () -> getMutinySessionFactory() - .withTransaction( (session, tx) -> session.merge( sampleEntity ) - .invokeUni( merged -> { - sampleJoinEntity.sampleEntity = merged; - merged.sampleJoinEntities.add( sampleJoinEntity ); - return session.persist( sampleJoinEntity ); - } ) - ) + .call( () -> getMutinySessionFactory().withTransaction( (session, tx) -> session + .merge( sampleEntity ) + .chain( merged -> { + sampleJoinEntity.sampleEntity = merged; + merged.sampleJoinEntities.add( sampleJoinEntity ); + return session.persist( sampleJoinEntity ); + } ) + ) ) - .then( () -> getMutinySessionFactory() + .call( () -> getMutinySessionFactory() .withTransaction( (session, tx) -> session .find( SampleJoinEntity.class, sampleJoinEntity.id ) .invoke( entity -> context.assertEquals( sampleJoinEntity.name, entity.name ) ) @@ -150,14 +156,14 @@ public void testDetachedReferenceWithMutiny(TestContext context) { test( context, getMutinySessionFactory() .withTransaction( (session, transaction) -> session.persist( sampleEntity ) ) - .then( () -> getMutinySessionFactory() + .call( () -> getMutinySessionFactory() .withTransaction( (session, tx) -> { sampleJoinEntity.sampleEntity = sampleEntity; sampleEntity.sampleJoinEntities.add( sampleJoinEntity ); return session.persist( sampleJoinEntity ); } ) ) - .then( () -> getMutinySessionFactory() + .call( () -> getMutinySessionFactory() .withTransaction( (session, tx) -> session .find( SampleJoinEntity.class, sampleJoinEntity.id ) .invoke( entity -> context.assertEquals( sampleJoinEntity.name, entity.name ) ) @@ -183,6 +189,7 @@ public void testTransientReferenceExceptionWithStages(TestContext context) { return session.persist( sampleJoinEntity ); } ) .handle( (session, throwable) -> { + context.assertNotNull( throwable ); context.assertEquals( CompletionException.class, throwable.getClass() ); context.assertEquals( IllegalStateException.class, throwable.getCause().getClass() ); context.assertEquals( TransientPropertyValueException.class, throwable.getCause().getCause().getClass() ); @@ -201,12 +208,13 @@ public void testTransientReferenceExceptionWithMutiny(TestContext context) { final SampleJoinEntity sampleJoinEntity = new SampleJoinEntity(); sampleJoinEntity.name = "Joined entity name"; - test( context, getMutinySessionFactory().withTransaction( (session, tx) -> { - sampleJoinEntity.sampleEntity = sampleEntity; - sampleEntity.sampleJoinEntities.add( sampleJoinEntity ); - return session.persist( sampleJoinEntity ); - } ) - .onItem().invoke( session -> context.fail( "Expected exception not thrown" ) ) + test( context, getMutinySessionFactory() + .withTransaction( (session, tx) -> { + sampleJoinEntity.sampleEntity = sampleEntity; + sampleEntity.sampleJoinEntities.add( sampleJoinEntity ); + return session.persist( sampleJoinEntity ); + } ) + .onItem().invoke( v -> context.fail( "Expected exception not thrown" ) ) .onFailure().recoverWithUni( throwable -> { context.assertNotNull( throwable ); context.assertEquals( IllegalStateException.class, throwable.getClass() );