Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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 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 can make this impossible task testing these scenarios possible.

This example shows use of @Resource 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.

...

Wiki Markup
{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.

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.

Wiki Markup
{snippet:id=code|url=openejb3/examples/testing-transactions/src/test/java/org/superbiz/injection/tx/MoviesTest.java|lang=java}

...