How does Glassfish manage Persistence Contexts (equality test)?
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
Hello Mitesh!
> GlassFish uses a proxy/delegate pattern to propagate persistence
> context. That is a proxy is injected into components and the actual EM
> from provider is the delegate and is switched as required.
Thank you for claryfing this!
So it's the container responsible for scanning @PersistenceContext annotations and for injection of the EntityManager, right? And it's the container's design decision that it will use proxy to the actual JPA-provider EM (like you've described it works in Glassfish) or if is not proxied?
> >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?
> You can use EntityManager.getDelegate() to get to the actual delegate
> and compare. I am curious though about why you need to compare for
> persistence context equality
You're right, when I've read my post at loud I thought to myself that it's quite weird why I would like to do such things :-)
I've described some rationale in my previous posts (in short: it's just for learning/testing purpose and a way of getting a proof that another PersistenceContext is used in certain situations).
By getting the delegate / unwrapping the EntityManager I can get access to the underlying JPA-provider EntityManager.
So, assuming I have this actual JPA-provider EntityManager - can I be sure (is it dictated by the spec?) that this object will be:
- equal across multiple calls within the same transaction and,
- different across multiple calls from different transactions?
Or perhaps the JPA provider is allowed to also do some proxying for his own purpose and such comparison of the unwrapped EntityManagers is also futile.
> Regards,
> Mitesh
> Persistence module lead for GlassFish
Thanks a lot for your answer and time.
Regards,
Piotr
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, 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
>
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, > 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
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, > > 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
Thanks for the clarification, Marina! :)
On 11/22/11 6:08 PM, Marina Vatkina wrote:
>
>
> 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, >> > 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
--
Jason Lee
Senior Member of Technical Staff, Oracle
GlassFish Team
Phone +1 (405) 216-3193
http://blogs.steeplesoft.com
Hi Guys,
It's the third time I'm trying to post this message - once it was attached to different topic, and the second one just vanished...
Nevertheless, I will repost the previously sent message and after, I'll add some explanation.
@Jason - You're right, I didn't precise it: I'm interested in container-managed transaction-scoped EntityManagers only.
Here goes the 'old' reply message:
-------------------------------------
Hi Richard!
Thanks for such fast reply :-)
I've read the page you quoted, but still - if the container manages the
EntityManagerFactory and just serves you the appropriate EntityManager
while seeing
@PersistenceContext
EntityManager em
than you still don't know how does it create the EntityManagers under
the hood.
My point is that I think that it's still spec-compliant if you provide
just a single EntityManager Proxy with each time someone requires it.
Therefore, each System.out.println(em) could return the same value while
it might represent different PersistenceContexts.
If it's the Glassfish responsibility, perhaps it follow the rule of
'Each EntityManager requested by @PersistenceContext represents exactly
one PersistenceContext'. If so, it would help me a lot. If not, maybe
there is some way to check what Persistence Context is referenced by
particular EntityManager?
-------------------------------------
Ok, and now some explanation "why do I bother with this whole thing". The point is, that recently I've bumped into a user which wanted to test what EntityManager he is referencing to or maybe more precisely - if the invoked method is in the same transaction (uses the same PersistenceContext) as the invoker.
Therefore, there was a code like this:
@Stateless
public class MyEJB {
@PersistenceContext
EntityManager em;
public void method1() {
System.out.println(em);
method2();
}
@TransactionAttribute(REQUIRES_NEW)
public void method2() {
System.out.println(em);
}
}
The client invokes the EJB's method1(). As you surely noticed, the method2() call will be made locally - not through the EJB, so the @TransactionAttribute doesn't have any meaning. There is no SessionContext#getBusinessObject(-).method2(), so the method2() will share the same transaction with method1().
The point that interested me is that it's not the first time I see people comparing the output of EntityManager#toString() method and, if they match, they treat it as a proof that the PersistenceContexts are the same.
That's why I'm asking - can such comparison be really meaningful or because of proxy'ing it's worthless?
Thanks in advance for your time Guys :-)
Regards.
There are no requirements for toString() method, or equals. So it can be
the same proxy or a different proxy, it can have its own toString or
delegated to the delegate (i.e. the EM instance from the JPA provider),
or to the Object#toString...
To compare transaction state, you can look at
TransactionSynchronizationRegistry, which has method getTransactionKey()
which might help...
-marina
forums@java.net wrote:
> Hi Guys,
>
> It's the third time I'm trying to post this message - once it was
> attached to
> different topic, and the second one just vanished...
>
> Nevertheless, I will repost the previously sent message and after,
> I'll add
> some explanation.
>
> @Jason - You're right, I didn't precise it: I'm interested in
> container-managed transaction-scoped EntityManagers only.
>
> Here goes the 'old' reply message:
Hi Marina,
Thank you for confirming my doubts about the unsafe toString() comparison.
I will definitely take a look at getTransactionKey() method.
Thanks for pointing this out!
Regards,
Piotr





GlassFish uses a proxy/delegate pattern to propagate persistence
context. That is a proxy is injected into components and the actual EM
from provider is the delegate and is switched as required.
>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?
You can use EntityManager.getDelegate() to get to the actual delegate
and compare. I am curious though about why you need to compare for
persistence context equality
Regards,
Mitesh
Persistence module lead for GlassFish
On 11/17/2011 3:43 AM, piotr@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