| Title: Testing Transactions Example |
| <a name="TestingTransactionsExample-Overview"></a> |
| # Overview |
| |
| Testing an EntityManager that uses the default, |
| PersistenceContextType.TRANSACTION, can be challenging due to Entities |
| detaching around transaction boundaries. If you were to take the [Injection of EntityManager Example](injection-of-entitymanager-example.html) |
| which uses an EXTENDED persistence context and switch it to a TRANSACTION |
| persistence context making no other changes, you'd find that the test would |
| fail. This would be because of the detach. |
| |
| Generally, when using an EntityManager with TRANSACTION persistence |
| context, your transaction should surround your use of the Entities |
| themselves, not just the use of the EntityManager. Using a [transaction in your unit test](unit-testing-transactions.html) |
| can make testing these scenarios possible. |
| |
| This example shows use of @PersistenceContext to have an *EntityManager* |
| with an *TRANSACTION* persistence context injected into a *@Stateful* bean |
| using the *@TransactionAttribute* annotation and a TestCase that runs test |
| code in a JTA *Transaction*. An EJB 3 @Entity bean is used with the |
| EntityManager to create, persist and merge data to a database. |
| |
| _The source for this example is in the "testing-transactions" directory |
| located in the [openejb-examples.zip](openejb:download.html) |
| available on the download page._ |
| |
| <a name="TestingTransactionsExample-TheCode"></a> |
| # The Code |
| |
| {snippet:id=code|url=openejb3/examples/testing-transactions/src/main/java/org/superbiz/injection/tx/MoviesImpl.java|lang=java} |
| |
| In the above bean code we see that the transaction attribute for all method |
| of the bean has been changed the default, which is |
| TransactionAttributeType.REQUIRED, to TransactionAttributeType.MANDATORY. |
| The MANDATORY transaction attribute is similar to REQUIRED in that the bean |
| method is guaranteed to be executed in a transaction, but with the added |
| restriction that if a transaction isn't started by the client before |
| calling the method, an exception will be thrown. |
| |
| The benefit of MANDATORY in this example is that it is impossible for the |
| client to get detached Entity issues. The client either has a transaction |
| and therefore gets Entities which are still attached and persistent, or the |
| client would get an exception stating that the use of a transaction is |
| mandatory. |
| |
| See the [Transaction Annotations](transaction-annotations.html) |
| page for a full description of the available transaction attributes. |
| |
| <a name="TestingTransactionsExample-Writingaunittestfortheexample"></a> |
| # Writing a unit test for the example |
| |
| The magic in the TestCase below is the *TransactionBean* @Stateless bean |
| which is tucked away as an inner class of the TestCase itself. With this |
| bean, we can call our test code within the scope of a container controlled |
| transaction. This allows our test code to use the EntityManager and the |
| Entities in the scope of a transaction, avoid any detach issues and |
| satisfying the TransactionAttributeType.MANDATORY requirement of our |
| MoviesImpl @Stateful bean. |
| |
| {snippet:id=code|url=openejb3/examples/testing-transactions/src/test/java/org/superbiz/injection/tx/MoviesTest.java|lang=java} |
| |
| Curious on the InitialContext parameters used? See the [Injection of DataSource Example](injection-of-datasource-example.html) |
| for an explanation of how any Resource can be configured via properties in |
| the TestCase itself or via an openejb.xml file. |
| |
| <a name="TestingTransactionsExample-Running"></a> |
| # Running |
| |
| Running the example is fairly simple. In the "testing-transactions" |
| directory of the [examples zip](openejb:download.html) |
| , just run: |
| |
| $ mvn clean install |
| |
| Which should create output like the following. |
| |
| |
| ------------------------------------------------------- |
| T E S T S |
| ------------------------------------------------------- |
| Running org.superbiz.injection.tx.MoviesTest |
| Apache OpenEJB 3.0 build: 20080408-04:13 |
| http://openejb.apache.org/ |
| INFO - openejb.home = |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions |
| INFO - openejb.base = |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions |
| INFO - Configuring Service(id=Default Security Service, |
| type=SecurityService, provider-id=Default Security Service) |
| INFO - Configuring Service(id=Default Transaction Manager, |
| type=TransactionManager, provider-id=Default Transaction Manager) |
| INFO - Configuring Service(id=movieDatabaseUnmanaged, type=Resource, |
| provider-id=Default JDBC Database) |
| INFO - Configuring Service(id=movieDatabase, type=Resource, |
| provider-id=Default JDBC Database) |
| INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory, |
| type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory) |
| INFO - Found EjbModule in classpath: |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/test-classes |
| INFO - Found EjbModule in classpath: |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/classes |
| INFO - Configuring app: |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/test-classes |
| INFO - Configuring Service(id=Default Stateless Container, type=Container, |
| provider-id=Default Stateless Container) |
| INFO - Auto-creating a container for bean TransactionBean: |
| Container(type=STATELESS, id=Default Stateless Container) |
| INFO - Loaded Module: |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/test-classes |
| INFO - Configuring app: |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/classes |
| INFO - Configuring Service(id=Default Stateful Container, type=Container, |
| provider-id=Default Stateful Container) |
| INFO - Auto-creating a container for bean Movies: Container(type=STATEFUL, |
| id=Default Stateful Container) |
| INFO - Configuring PersistenceUnit(name=movie-unit) |
| INFO - Loaded Module: |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/classes |
| INFO - Assembling app: |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/test-classes |
| INFO - Jndi(name=TransactionBeanLocal) --> |
| Ejb(deployment-id=TransactionBean) |
| INFO - Created Ejb(deployment-id=TransactionBean, ejb-name=TransactionBean, |
| container=Default Stateless Container) |
| INFO - Deployed |
| Application(path=/Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/test-classes) |
| INFO - Assembling app: |
| /Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/classes |
| INFO - PersistenceUnit(name=movie-unit, |
| provider=org.apache.openjpa.persistence.PersistenceProviderImpl) |
| ERROR - JAVA AGENT NOT INSTALLED. The JPA Persistence Provider requested |
| installation of a ClassFileTransformer which |
| requires a JavaAgent. See |
| http://openejb.apache.org/3.0/javaagent.html |
| INFO - Jndi(name=MoviesLocal) --> Ejb(deployment-id=Movies) |
| INFO - Created Ejb(deployment-id=Movies, ejb-name=Movies, container=Default |
| Stateful Container) |
| INFO - Deployed |
| Application(path=/Users/dblevins/work/openejb-3.0/examples/testing-transactions/target/classes) |
| Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.25 sec |
| |
| Results : |
| |
| Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 |
| |
| |