users@glassfish.java.net

Re: Surprising JPA (Toplink) Behaviour (glassfish v1 UR1)

From: <glassfish_at_javadesktop.org>
Date: Sat, 17 Mar 2007 22:54:03 PST

I have been going to great lengths to explore the various options that I have in order
to unify the schizophrenic codebase that I have before me. I am reluctant to change
everything into being application-managed, because of the annoying need to switch from
UserTransaction to EntityTransaction (thankfully pointed out by Marina Vatkina above.)

I don't think that I have the time to figure out how to make everything use @PersistenceUnit
literally, because i have a lot of JPA code that doesn't reside directly in managed components,
and therefore they don't get any annotation-processor love like the JSF managed beans do. And,
frankly, it's not clear what sort of managed-component I'd stuff that code into anyway. I'd like
my application to be deployable in a plain WAR -- that seems to limit my managed-component
options to servlets, jax-ws services, and JSF managed-beans.

But what if I can take an EMF that I obtain in these managed-components out into the
other code -- that should ensure that everything is using the same EMF, and hopefully
alleviate the stale data woes, correct? Regardless of whether I am correct in that assumption,
(and please do tell me if it's ill-conceived) I did proceed from it with experiment, at length.

The basic idea was to start by logging the hashcode of the EMFs used by different parts of
the code and keep playing around until I could get both halves of the code to be using the
same EMF. This turns out to have been much, much harder than it sounds like it should be.

The reason that it was difficult is that the POJO code needs to get an EMF very early in
the startup process, because one of the first things that my application does is generate
some xml files and write them to the static docroot. This code may again be triggered
later to regenerate the xml files after the JSF pages have done some edits to the database.
The JSF managed-beans, on the other hand, may never be instantiated -- for example, say
no-one needs to do any data entry on that day -- and may therefore never be able to inject
an EMF into my hand-rolled singleton/factory.

So, to be clear, my general strategy was to pick some managed component, arm it with
@PersistenceUnit, and a @PostConstruct method that calls a static setter on MyFactory.

Sensible?

The first managed component that I chose was a servlet I had lying around (the one that
triggered the xml-generation from its init() method) and decided to have it provide the EMF
for the other half of the code. The result? The hashcodes revealed that the JSF managed-bean
used during data-entry is still using a different EMF han the servlet provided
to the POJO code.

Darn. Well, maybe that's because my servlet had nothing to do with JSF. So I wrote a replacement
for the FacesServlet, one that makes a private FacesServlet instance and delegates
all calls to it. Although the exercise resulted in a fully-functioning replacement for FacesServlet,
the EMF that it injected into my POJO code is also different from the EMF being used by the
relevant JSF managed-bean that does the data entry. Moreover, it's different from the EMF that
glassfish provided to the first servlet.

So I added the @PersistenceUnit/_at_PostConstruct directly to the JSF managed bean in
question. Even though i can't depending on this managed-bean being instantiated, I was
desparate to see what would happen if both halves of my system ended up using the same
EMF. Finally, the logging showed hashcodes that proved that both the POJO code and
the JSF managed-bean were using the same EMF. W00t! Sadly, this did not alleviate
the stale data issues. (!?) Pardon me, but shouldn't it have?

Also, there's something I'd like to know: if EMFs are so dreadfully expensive to create, why
doesn't glassfish bother to inject the same one into all of these different managed components?
Let me show you the astonishing collection of different EMF instances that I'm seeing in my
logs...

RCCL PersistenceUnitInjector: injecting emf @PostConstruct. // my FacesServlet facade
RCCL ServerConfig receiving EntityManagerFactory: 9271677
RCCL DashboardController: injected emf = 1456184 // one JSF managed-bean
RCCL RestaurantsController: injected emf=9319553 // another JSF managed-bean
RCCL RestaurantMenuItemsController: injected emf=12990151 // another JSF managed-bean
RCCL RestaurantCategoriesController: injected emf=2363461 // another JSF managed-bean.

It goes on, and on, and on. Apparently glassfish doesn't think it's important that all of my
code use the same EMF, which I find surprising since I'm getting the sense in this forum
that glassfish ought to think otherwise.

But perhaps that is all besides the point, since the one thing that I did managed to learn from
all of this is that even when I did manage to finally get the same EMF into both halves of
my code I'm still getting staleness of data.
[Message sent by forum member 'pohl' (pohl)]

http://forums.java.net/jive/thread.jspa?messageID=208599