users@glassfish.java.net

Re: How does Glassfish manage Persistence Contexts (equality test)?

From: Jason Lee <jason.d.lee_at_oracle.com>
Date: Thu, 17 Nov 2011 08:12:02 -0600

I think there will be more than on EntityManager, as they are not
thread-safe (which is why you shouldn't inject EMs into SFSBs, iirc).
The EntityManagerFactory, either implicit by injection or explicitly in
user code, creates new EntityManagers as needed. When done, again,
either implicitly or explicitly in user code, the EntityManager is
closed, at which point I believe the transaction associated with the EM
may be torn down as well. Given the semantics of the EM interface
(EntityManager.close()), I would expect that the EMs are not pooled,
though I don't see that is being a major concern to me as an application
developer. If they *are* pooled, that strikes me as an implementation
detail that I need not worry about. Clearly, though, the OP has some
concerns in that area, so I could be missing something. I don't,
however, understand where the OP is heading with the question, to be
honest. :)

Perhaps I should be more clear on the EM creation. The spec text quoted
below talks about "*container-managed* EntityManagers". That means, of
course, injected instances, such as in the SLSB example below, the
container creates the EntityManager (either new or from a pool, it
seems) and provides it to the user's application. In stateful
scenarios, where the use of container-managed EMs is not correct, the
user is responsible for managing the lifecycle of the EM. Completely
from the hip, that might look something like this:

@Stateful
public class SomeBean {
     @PersistenceUnit
     private EntityManagerFactory emf;

     public someMethod() {
         EntityManager em = emf.createEntityManager();
         em.joinTransaction();
         // Do some work...
         em.close();
     }
}

This EntityManager can be passed as a parameter to other methods, as
needed, but should be destroyed at the end of someMethod() and should
never be saved for use from a later call. Unless you like race
conditions. :) All that so say this it's *not* necessarily "*the
container responsibility* to manage the EntityManagers". Whether or not
that's true depends on where you're using the EM.

That doesn't clear up the question as to whether two EMs are the same
instance or not, I guess, but, like I said, I'm not sure why it would
matter. Just work with the EM you're given or create and let the system
worry about the rest. :)

On 11/17/11 6:01 AM, Richard Kolb wrote:
> Hi Piotr
>
> I won't pretend to understand the inner working of JPA inside the
> container, but I did see this interesting doc from TomEE that may help
> :http://openejb.apache.org/jpa-concepts.html
>
> /Calling entityManagerFactory.createEntityManager() twice results in
> two separate EntityManager instances and therefor two separate
> PersistenceContexts/Caches. -- It is almost never a good idea to have
> more than one instance of an EntityManager in use (don't create a
> second one unless you've destroyed the first)/
>
> -----
> When I do the below and the EJB is invoked all over the place, do the
> EntityManager's get pooled since I did not use the factory, is there
> only one ? I am not sure.
>
> @Stateless
> public class PartyFacadeCRUDBean {
> @PersistenceContext(unitName = "BLA")
> private EntityManager em;
>
> }
>
>
> Hope this helps
> regards
> Richard.
>
>
>
> On 17 November 2011 13:43, <piotr_at_piotrnowicki.com
> <mailto:piotr_at_piotrnowicki.com>> wrote:
>
> Howdy Guys,
>
> I've been asking this question for some time now (StackOverflow,
> EclipseLink, JavaRanch) - without any luck.
>
> If I correctly understand the JPA 2.0 specification, it's the
> container (Glassfish) responsible for processing the
> persistence.xml, discovering the JPA Provider and creating an
> EntityManagerFactory. If so, than it's *the container
> responsibility* to manage the EntityManagers? In the
> specification, there is the following part:
>
> "When operating with a third-party persistence provider, the
> container uses the contracts defined in section 7.9 to create and
> destroy container-managed persistence contexts. *It is undefined
> whether a new entity manager instance is created for every
> persistence context, or whether entity manager instances are
> sometimes reused*. Exactly how the container maintains the
> association between persistence context and JTA transaction is not
> defined."
>
> As I understand it, it allows the container (or the jpa-provider?)
> to either create new EntityManager each time or reuse it's
> instances (perhaps using a proxy?).
>
> If so, than how is Glassfish managing the EntityManagers?
> Is there a way I can check two EntityManager instances for equality?
> Can I do naive System.out.println(em) and check the value for
> PersistenceContexts equality?
>
> Thanks in advance!
>
> Regards,
> Piotr
>
>


-- 
Jason Lee
Senior Member of Technical Staff, Oracle
GlassFish Team
Phone +1 (405) 216-3193
http://blogs.steeplesoft.com