users@glassfish.java.net

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

From: Marina Vatkina <marina.vatkina_at_oracle.com>
Date: Tue, 22 Nov 2011 16:08:10 -0800

Jason Lee wrote:
> 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).

Into Servlets. Extended EMs (e.g.) are intended for SFSB...
> 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.

Not quite. EM is closed by the user code (if the user code created it),
when the user code chooses to do so. EM is closed by the container by
more complicated set of rules...

A JTA transaction can be either completed by the user (via
UserTransaction), and EM is not closed at that point, or by a server (in
case of a CMT EJB), where non-extended EM is closed if it was created by
the container. EM can be non-transactional as well (where similar rules
apply).

> 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

It is correct, but usually extended EM is used...

-marina

> , 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