Hi Emmanuel!
My point is: Some features of seam-persistence are more a seam-hibernate (as upgrade path
from Seam2 this makes perfect sense I guess) than a general JPA thingy. They only work
with Hibernate and cannot be generalized to other JPA providers! And even if you use
Hibernate, then there are a few restrictions which should get added to the documentation.
I'll try to sum up:
If you use a scope bigger than @RequestScoped on the EnitityManagerProducer then:
* This only works with Hibernate and FlushMode.MANUAL. No other JPA provider will do since
the EntityManager impls are usually _not_ Serializable.
* The problem is that most queries will be performed inside a @Transactional bracelet thus
they might have an open transaction. In this case there is no temp-transaction which could
be rollbacked. Thus the 'baby non auto-flush' doesn't work out I fear.
* Also in JPA managed entities must not get accessed from multiple threads in parallel.
All scopes longer than @RequestScoped are subject of being hit by parallel AJAX calls or
requests from multiple windows. It's only a matter of load to get this situation. I
was easily able to reproduce such scenarios with JMeter [1] with 50 parallel threads.
* EntityManager#lock must not get used.
* native Queries might return wrong results.
* non-trivial Queries might return wrong results.
* no select for update allowed.
But I agree completely with you that a Serializable EntityManager would be a BIG benefit.
I frankly fear this is only possible by dropping all the pessimistic locking stuff and not
doing so much things automatically. There is a JPA-like project called eBean [2] which
does exactly that. But it's not a JPA provider exactly because of that...
Imo the easiest way to cope with that situation is to emulate the transactional stuff of
EJB with an extended EntityManager. Opening the transaction once the outer @Transactional
gets entered, and committing/rollback + closing the EntityManager as soon as you leave the
outermost @Transactional method. This will detach all entities immediately, so they can be
transfered, used, whatever... One just needs to em.merge them to get them stored later.
I'm not sure about Hibernate, but OpenJPA and Eclipselink both store _loaded and
_dirty bitfields in detached entities and this info will also get serialized along the
line.
LieGrue,
strub
[1]
From: Emmanuel Bernard <emmanuel(a)hibernate.org>
Subject: Re: [seam-dev] [seam-persistence] ManagedPersistenceContextExtension
To: "Mark Struberg" <struberg(a)yahoo.de>
Cc: "John D. Ament" <john.d.ament(a)gmail.com>,
"seam-dev(a)lists.jboss.org" <seam-dev(a)lists.jboss.org>
Date: Monday, July 11, 2011, 12:08 AM
Hibernate has the notion of
FlushMode.MANUAL to prevent operations from being pushed to
the DB even upon queries. JPA has a baby version of that
with extended persistence contexts behaving outside
transactions.
Yes some methods like lock are not allowed when the em is
expected to be passivated. But that's not a reason to
disable a useful feature (passivation) altogether.
Passivation is sometimes not possible but that far from
your statement "This is never _never_ NEVER true. The
EntityManager is not Serializable!".
Emmanuel
PS: There are more efficient ways to passivate an
entityManager than serializing it with some help from the
persistence provider. I don't remember if we ever finished
this work.
>
On 11 juil. 2011, at 01:44, Mark Struberg <struberg(a)yahoo.de>
wrote:
> There are a few problems which can happen:
>
> a.) EmtityManager#lock(java.lang.Object o,
javax.persistence.LockModeType lockModeType); and others
with LockType#PESSIMISTIC_*
>
> b.) Consider you have an Entity dirty or a fresh one
created with em.persist(). And now you do a non-trivial
query. In order to guarantee that this new/modified entity
gets evaluated properly, JPA _explicitly_ allows the
EntityManager to write those values into the database.
Voila, you have your open transaction! Not too many people
are aware of that but yes, querying from the database can
lead to a SQL INSERT or SQL UPDATE into the database! Of
course, you better _not_ commit those changes immediately
;)
>
>
> LieGrue,
> strub
>
>
>
> --- On Sun, 7/10/11, John D. Ament <john.d.ament(a)gmail.com>
wrote:
>
> From: John D. Ament <john.d.ament(a)gmail.com>
> Subject: Re: [seam-dev] [seam-persistence]
ManagedPersistenceContextExtension
> To: "Mark Struberg" <struberg(a)yahoo.de>
> Cc: "Stuart Douglas" <stuart.w.douglas(a)gmail.com>,
seam-dev(a)lists.jboss.org
> Date: Sunday, July 10, 2011, 11:29 PM
>
> But is the select for update done inside the
entitymanager object or a query instance? I don't
think EntityManager.find(Class,Id) does any type of hold on
the object found.
>
> John
>
>
> On Sun, Jul 10, 2011 at 7:15 PM, Mark Struberg <struberg(a)yahoo.de>
wrote:
>
> Stu, whenever you do a "select for update" or any
manual locking, you will end up with an EntityManager which
cannot be transfered to another node. Even if hibernate
marks it's EntityManager Serializable, it just isn't if I
didn't miss something!
>
>
>
>
> LieGrue,
>
> strub
>
>
>
> --- On Sun, 7/10/11, Stuart Douglas <stuart.w.douglas(a)gmail.com>
wrote:
>
>
>
>> From: Stuart Douglas <stuart.w.douglas(a)gmail.com>
>
>> Subject: Re: [seam-dev] [seam-persistence]
ManagedPersistenceContextExtension
>
>> To: "Mark Struberg" <struberg(a)yahoo.de>
>
>> Cc: seam-dev(a)lists.jboss.org
>
>> Date: Sunday, July 10, 2011, 11:07 PM
>
>>
>
>> On 11/07/2011, at 4:07 AM, Mark Struberg wrote:
>
>>
>
>>> Hi folks!
>
>>>
>
>>> While reviewing an OWB bug report, 2 questions
came
>
>> up:
>
>>>
>
>>> a.) EnvironmentUtils#isEEEnvironment() relies
on the
>
>> absence of 'javax.ejb.Stateless' to decide if a
>
>> PersitenceUnit gets injected or if you need to do
it
>
>> yourself. I think this is an unrelieable
assumption. E.g.
>
>> there are a few Extensions which emulate Stateless
Session
>
>> beans via a CDI Extension by morphing them into
>
>> @ApplicationScoped.
>
>>
>
>> This is not ideal, but I don't think there is
really any
>
>> portable way to detect if the environment is an
EE
>
>> environment or not. I was originally planning to
add a
>
>> method for configuring this, but it appears I did
not get
>
>> around to it.
>
>>
>
>>>
>
>>> b.) in
>
>>
ManagedPersistenceContextExtension#registerManagedPersistenceContext
>
>> you register the bean for the EntityManager as
>
>> passivationCapable. This is never _never_ NEVER
true. The
>
>> EntityManager is not Serializable! There is imo no
way to
>
>> have an EntityManager in a bean scoped other than
>
>> @RequestScoped or shorter (e.g.
@TransactionalScoped). Any
>
>> other trick is not working in a portable way. This
is mainly
>
>> caused by JPA still supporting pessimistic locking
(_real_
>
>> locks in the database) as first class citizens.
>
>>>
>
>>
>
>> Without this it is not possible to have a
conversation
>
>> scoped entity manager. The hibernate EntityManager
is in
>
>> fact Serializable. Locks should not be a problem
as long as
>
>> you do not attempt to serialise the EM in the
middle of a
>
>> transaction.
>
>>
>
>> Stuart
>
>>
>
>>
>
>>> But I'd be happy if anyone could enlighten me
and tell
>
>> us how it works ;)
>
>>>
>
>>> LieGrue,
>
>>> strub
>
>>>
_______________________________________________
>
>>> seam-dev mailing list
>
>>> seam-dev(a)lists.jboss.org
>
>>>
https://lists.jboss.org/mailman/listinfo/seam-dev
>
>>
>
>>
>
> _______________________________________________
>
> seam-dev mailing list
>
> seam-dev(a)lists.jboss.org
>
>
https://lists.jboss.org/mailman/listinfo/seam-dev
>
>
>
>
>
> _______________________________________________
> seam-dev mailing list
> seam-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/seam-dev