package org.javaee7.jpa.listeners; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import javax.inject.Inject; import java.util.List; import java.util.concurrent.TimeUnit; import static org.javaee7.jpa.listeners.MovieListener.*; import static org.junit.Assert.*; /** * In this sample we're going to query a simple +JPA Entity+, using the +JPA EntityManager+ and perform a findAll, * persist, merge, and remove operations. By calling these operations we want to demonstrate the behaviour of +Entity * Listener Methods+: +@PostLoad+, +@PrePersist+, +@PostPersist+, +@PreUpdate+, +@PostUpdate+, +@PreRemove+, * +@PostRemove+ defined on +MovieListener+: * * include::MovieListener[] * * The following +JPA Entity+, represents a Movie which has a name and a comma separated list of actors: * * include::Movie[] * * * @author Roberto Cortez */ @RunWith(Arquillian.class) public class JpaListenersTest { @Inject private MovieBean movieBean; /** * We're just going to deploy the application as a +web archive+. Note the inclusion of the following files: * * [source,file] * ---- * /META-INF/persistence.xml * /META-INF/create.sql * /META-INF/drop.sql * /META-INF/load.sql * ---- * * The +persistence.xml+ file is needed of course for the persistence unit definition. A datasource is not * needed, since we can now use the new default datasource available in +JEE7+. We're also using the new * +javax.persistence.schema-generation.*+ propertires to create, populate and drop the database. */ @Deployment public static WebArchive createDeployment() { WebArchive war = ShrinkWrap.create(WebArchive.class) .addPackage("org.javaee7.jpa.listeners") .addAsResource("META-INF/persistence.xml") .addAsResource("META-INF/create.sql") .addAsResource("META-INF/drop.sql") .addAsResource("META-INF/load.sql"); System.out.println(war.toString(true)); return war; } /** * In the test, we're just going to invoke the different operations in sequence keeping in mind that each * invocation might be dependent of the previous invoked operation. */ @Test public void testListeners() throws Exception { List<Movie> movies = movieBean.listMovies(); // <1> 4 movies in the database, so +@PostLoad+ method called 4x assertEquals(4, movies.size()); assertFalse(prePersistInvoked); assertFalse(postPersistInvoked); movieBean.createMovie(); // <2> On persist both +@PrePersist+ and +@PostPersist+ are called assertTrue(prePersistInvoked); assertTrue(postPersistInvoked); movies = movieBean.listMovies(); // <3> 5 movies now, so +@PostLoad+ method called 5x assertEquals(5, movies.size()); assertTrue(movies.contains(new Movie(5))); assertFalse(preUpdateInvoked); assertFalse(postUpdateInvoked); movieBean.updateMovie(); // <4> On merge both +@PreUpdate+ and +@PostUpdate+ are called assertTrue(preUpdateInvoked); assertTrue(postUpdateInvoked); movies = movieBean.listMovies(); // <5> Still 5 mpvies, so +@PostLoad+ method called again 5x assertEquals(5, movies.size()); assertEquals("Inception2", movies.get(2).getName()); assertFalse(preRemoveInvoked); assertFalse(postRemoveInvoked); movieBean.deleteMovie(); // <6> On remove both +@PreRemove+ and +@PostRemove+ are called assertTrue(preRemoveInvoked); assertTrue(postRemoveInvoked); movies = movieBean.listMovies(); // <7> 4 movies now, so +@PostLoad+ method called 4x assertFalse(movies.isEmpty()); assertEquals(4, movies.size()); assertFalse(movies.contains(new Movie(3))); assertTrue(MovieListener.entityListenersCountDownLatch.await(0, TimeUnit.SECONDS)); } }