deltaspike-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Struberg <strub...@yahoo.de>
Subject Re: Extended EntityManager
Date Sun, 19 Apr 2015 08:59:07 GMT
Ah oki, I see. Didn’t catch that you store it away.

There are quite a few tricky parts in practice with that approach (been there, done that..).
Not ultimately problems but at least points you need to be aware off.

The first one is the serialisation issue I talked about in my blog post already.
The second one is that you must not touch the same EntityManager in parallel requests. But
as the ConversationContexts is basically just a fraction of the Session (and gets stored in
there), you will likely hit that.

E.g. imagine a sendRedirect call in the middle of request A. Purely calling sendRedirect will
_not_ finish the thread which contains request A. It might still need to do some work, e.g.
send a message, clean up stuff etc. The problem now happens if your clients browser executes
the redirect faster (resulting in Request B) than you could finish Request A. And in that
case your app will blow up by accessing the same EM from 2 different threads. 

You will most likely not hit this issue during testing but _only_ under high load in production
:(


LieGrue,
strub



> Am 18.04.2015 um 13:34 schrieb titou10 <titou10.titou10@gmail.com>:
> 
> Mark,
> We keep the EM in the conversation scope, but we expose it at the request scope
> A new EM is created only when there is no one currently in the conversation scope, so
we have the same EM for the duration of the conversation, short or long:
> It is very close to what Seam 2 did
> 
> @ConversationScoped
> public class EntityManagerProducer {
> 
> =====>   private transient EntityManager em;
> 
>   @PersistenceUnit
>   private EntityManagerFactory    emf;
> 
>   @Produces
>   @RequestScoped
>   protected EntityManager creerEntityManager() {
> ======>      if (em == null) {
> ======>         em = emf.createEntityManager();
> ======>      }
> ======>      return this.em;
>   }
> 
> Le 2015-04-18 01:35, Mark Struberg a écrit :
>> But in your example only the bean ‚holding‘ the producer method is @ConversationScoped.
The EntityManager you create is only @RequestScoped (which is good imo!), right? So the lifecycle
of the EM will effectively be 1-per-prequest.
>> 
>> LieGrue,
>> strub
>> 
>> 
>>> Am 17.04.2015 um 22:30 schrieb titou10 <titou10.titou10@gmail.com>:
>>> 
>>> I can't comment on the DS/JPA example, but that's why the solution we use keeps
the EM instance in a variable, variable held in the @ConversationScoped Bean that "contains"
the producer that "exposes" this EM in the @RequestScope
>>> The EM is opened/closed only on conversation boundaries (short or long) , very
similar to what Seam 2 does (In CDI,  Conversations length is not exactly the same as in Seam
Conversations)
>>> Denis
>>> 
>>> Le 2015-04-17 16:05, Ludovic Pénet a écrit :
>>>> Thanks to everybody for your valuable adviced.
>>>> 
>>>> I ended with an @ApplicationScoped EntityManagerProducer, producing @ViewAccessScoped
ExtendedEntityManager.
>>>> ExtendedEntityManager is identical to DS JPA example.
>>>> 
>>>> So, something very close from DS JPA page example.
>>>> 
>>>> http://deltaspike.apache.org/documentation/jpa.html#_extended_persistence_contexts
>>>> 
>>>> In fact, I am still a bit puzzled by DS JPA example, because the EntityManager
it produces is @RequestScoped.
>>>> 
>>>> So, when I basically copied/pasted it, the EM was just opened and closed
on every request. And, for an example, session was closed when some hibernate proxies were
accessed during serialization...
>>>> 
>>>> Do I miss something obvious, or should the doc rather mention that one should
use a scope such as @ViewScoped, @SessionScoped or @ViewAccessScoped rather than @RequestScoped
?
>>>> 
>>>> Ludovic
>>>> 
>>>> 
> 


Mime
View raw message