users@glassfish.java.net

Re: Cleaning out EclipseLink cache between EJBs

From: Phillip Ross <phillip.w.g.ross_at_gmail.com>
Date: Fri, 2 Dec 2011 09:45:13 -0500

Hi Laird,

The method I have been using for awhile in my integration testing that
run in glassfish embedded uses javax.persistence.Persistence to create
an entity manager factory. I dont know if it's supposed to work or
not, but it does :)

Here are some details:

Using TestNG to run the tests, each of my integration test suites has
a @BeforeSuite method which fire up glassfish embedded and places a
reference to the javax.ejb.embeddable.EJBContainer into a singleton I
call EJBContainerReferenceHolder. Each test class has a @BeforeClass
method which pulls the container ref from the singleton and gets the
jndi context from the ejbContainer ref. Any EJBs I lookup from this
context appear to be the exact EJBs that I find to be injected by the
container. Similarly, any EMF/EMs I create from
javax.persistence.Persistence appear to be the same ones that are
injected into the EJBs. All of my test code can use these
interchangeably, and all transaction control and cache manipulation
seem to work seamlessly in the test code. The test code is not
trivial either... somewhere between 1000 and 1200 separate tests and a
lot of them test for cache consistency and microbenchmarking cached
operations. It seems to all work and is cleaner than it may sound.
And performance-wise I believe the longest running test suite appears
to run in under 3 minutes when timing dependent tests are disabled
(such as tests that validate time-dependent cache invalidations).

The best part is that it has done a good job of exposing a few of my
own bugs as well as bugs in glassfish and eclipselink.

Hope that helps!
- Phillip

On Wed, Nov 30, 2011 at 12:12 PM, Laird Nelson <ljnelson_at_gmail.com> wrote:
> I'm looking at improving the performance of our integration tests.
>
> We have some EJBs with injected persistence contexts in them.
>
> At the moment, because of EclipseLink session cache issues, we bring up and
> destroy an instance of embedded Glassfish in between each test, not just in
> between each test suite.
>
> As you might imagine, the performance is horrible.
>
> (If instead we bring embedded Glassfish up, run a test suite, and then take
> embedded Glassfish down, then the session cache has some results in it that
> last between integration tests.  For a variety of reasons we don't want this
> to be the case.)
>
> (We also don't want to turn off the session cache, as some of our tests are
> designed to make sure that it is working.)
>
> (Fun mess, huh?)
>
> The general line of attack I had in mind was to deploy a test EJB alongside
> our other EJBs that--when appropriately called--could somehow grab ahold of
> the proper EntityManagerFactory, invoke its getCache() method, and then
> invoke evictAll().  The test harness would ensure that this "cache cleaner"
> EJB would be called in between individual tests.
>
> However, a persistence context is defined by the specification as existing
> in the java:comp/env namespace, and the comp/env namespace is per-component
> (so in this case per-EJB).  This means that at least according to the
> specification that having EJB #2 try to look up EJB #1's persistence context
> using JNDI is not likely to work.
>
> Having said that, EJB #2 (the cache cleaner EJB) would only actually need a
> handle on the EntityManagerFactory, so perhaps there's some other way to get
> ahold of that.
>
> Does anyone have any further ideas here?  Or, equally helpfully, some reason
> for why this is an idiotic thing to try to do?  :-)
>
> Thanks,
> Laird
>
> --
> http://about.me/lairdnelson
>