You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by Kevin Mudrick <km...@healthmarketscience.com> on 2008/04/08 21:59:28 UTC
variation on injection-of-entitymanager test
Hi,
If I change the injection-of-entitymanager test code to be
container-managed and require new transactions for ejb calls, the unit
tests fail:
ex:
@Stateful(name = "Movies")
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class MoviesImpl implements Movies {
@PersistenceContext(unitName = "movie-unit", type =
PersistenceContextType.TRANSACTION)
private EntityManager entityManager;
...
I'm pretty sure this is a valid case, but the operation's don't seem to
be commiting on each call into the bean from the test code:
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 3.988
sec <<< FAILURE!
test(org.superbiz.injection.jpa.MoviesTest) Time elapsed: 3.939 sec
<<< FAILURE!
junit.framework.AssertionFailedError: Movies.getMovies() expected:<0>
but was:<3>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:277)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:195)
at org.superbiz.injection.jpa.MoviesTest.test(MoviesTest.java:61)
Why is this so? Does some other configuration need to change to support
this?
Thanks,
Kevin
Re: variation on injection-of-entitymanager test
Posted by David Blevins <da...@visi.com>.
On Apr 8, 2008, at 12:59 PM, Kevin Mudrick wrote:
> Hi,
>
> If I change the injection-of-entitymanager test code to be container-
> managed and require new transactions for ejb calls, the unit tests
> fail:
>
> ex:
>
> @Stateful(name = "Movies")
> @TransactionManagement(TransactionManagementType.CONTAINER)
> @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
> public class MoviesImpl implements Movies {
> @PersistenceContext(unitName = "movie-unit", type =
> PersistenceContextType.TRANSACTION)
> private EntityManager entityManager;
>
> ...
>
>
> I'm pretty sure this is a valid case, but the operation's don't seem
> to be commiting on each call into the bean from the test code:
>
> Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed:
> 3.988 sec <<< FAILURE!
> test(org.superbiz.injection.jpa.MoviesTest) Time elapsed: 3.939
> sec <<< FAILURE!
> junit.framework.AssertionFailedError: Movies.getMovies()
> expected:<0> but was:<3>
> at junit.framework.Assert.fail(Assert.java:47)
> at junit.framework.Assert.failNotEquals(Assert.java:277)
> at junit.framework.Assert.assertEquals(Assert.java:64)
> at junit.framework.Assert.assertEquals(Assert.java:195)
> at org.superbiz.injection.jpa.MoviesTest.test(MoviesTest.java:
> 61)
>
>
> Why is this so? Does some other configuration need to change to
> support this?
Hi Kevin.
The basics of what's happening is that when the example was switched
from PersistenceContextType.EXTENDED to
PersistenceContextType.TRANSACTION the persistence contract changed in
a subtle way.
With EXTENDED, Entities stay attached outside the scope of a
transaction and you can then use them again in a subsequent
transaction without having to re-fetch them from the EntityManager via
merge or something similar. The test code, which isn't running in a
transaction, is able to pull/pass Entities from/to the Stateful EJB,
which runs in a transaction, only because of the EXTENDED persistence
context.
With TRANSACTION as the PersistenceContext for the EntityManager, the
Entities returned from the Stateful EJB detach when the transaction
completes. By the time the test case gets the java.util.List of
entities, they've all been detached and often times (depending on the
persistence provider) not even filled with data. When detached, the
Entities leave the "sight" of the EntityManager and are considered
plain, non-persistent, java objects. In the case of lists it's common
to find that the EntityManager gave a "lazy" list and won't actually
read the data associated with the query unless you iterate over the
list in the transaction. Both OpenJPA and Hibernate do that, not sure
of others.
This document shows some techniques for running your test case in a
transaction so that you can successfully test an EntityManager using a
TRANSACTION persistence scope. http://openejb.apache.org/3.0/unit-testing-transactions.html
Note that you'll still run into the detach issue if the bean uses
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW). Better
would be to stick with the default of REQUIRED or (my preference) go
with MANDATORY so that it isn't possible for others to call your bean
outside of a transaction and get confusing results.
We have an example with that exact setup that you might find useful.
It's the directory "testing-transactions" in the openejb-
examples-3.0.zip released yesterday and available on the download page.
Hope this helps!
-David