You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@deltaspike.apache.org by Xavier Dury <ka...@hotmail.com> on 2016/07/04 08:19:31 UTC

Some thoughts about EntityManagerResolver and EXTENDED PersistenceContext

Hi,

I know that the EXTENDED PersistenceContext usage is not recommended by the DeltaSpike team but I would like to have a discussion about it.

I am currently developing a small-scale intranet application where our core-business entity model has a lot of levels which can be lazily expanded/collapsed in the UI (written in JSF). In this case, I really like to be able to use an EXTENDED PersistenceContext and not really care about eagerly loading all associations as, most of the time, deep levels won't even be expanded (the decision is left to the user to expand what is needed). And this is the concept that made me like Seam when it was first released.

Now, I have some concerns about the EntityManagerResolver:

- As an EntityManagerResolver kinda "extracts" the EM from its owning @Stateful bean, what guarantees do I have that this EM won't be used in concurrent (AJAX) requests? If I am not mistaken, all method calls on a @Stateful bean must be synchronized/locked but as the EM is not thread-safe and won't be called in the context of a call on its owning SFSB, this could be problematic. (Since JPA 2.1, I've seen a synchronization attribute on @PersistenceContext but it has nothing to do with concurrent synchronization.)

- Correct me if I am wrong but the JEE spec does not (yet) define how an EM that was "extracted" from its owning bean should behave.

Therefore, wouldn't it be better to replace the EntityManagerResolver by some sort of EntityManagerHolder like this one:

public interface EntityManagerHolder {
    
    <T> T executeCallback(EntityManagerCallback<T> callback);
}

public interface EntityManagerCallback<T> {

    T execute(EntityManager entityManager);
}

and have it implemented like this:

@Stateful
@TransactionManagement(BEAN) // TXs should not be handled here
@ViewScoped // for example
public class MyEntityManagerHolder implements EntityManagerHolder {

    @PersistenceContext(type = EXTENDED)
    private EntityManager entityManager;

    public <T> T executeCallback(EntityManagerCallback<T> callback) {
        return callback.execute(this.entityManager);
    } 
}

Here, all calls on the EntityManager will happen inside a call on the SFSB which should guarantee that only one thread at a time may use the EM and it also circumvents the gap in the specification.

What do you think? Is there something I forgot to take into account?

Thanks,

Regards,

Xavier 		 	   		  

RE: Some thoughts about EntityManagerResolver and EXTENDED PersistenceContext

Posted by Xavier Dury <ka...@hotmail.com>.
Hi Gerhard,

good idea, I was thinking of wrapping my EM returned from EntityManagerResolver.resolveEntityManager() in some sort of SynchronizedEntityManagerWrapper but a decorator is really nice too.

Thanks,

Xavier

----------------------------------------
> From: gpetracek@apache.org
> Date: Fri, 8 Jul 2016 15:44:17 +0200
> Subject: Re: Some thoughts about EntityManagerResolver and EXTENDED PersistenceContext
> To: users@deltaspike.apache.org
>
> hi xavier,
>
> if you are using @org.apache.deltaspike.jpa.api.transaction.Transactional,
> you can use a decorator like:
>
> @Decorator
> @Priority(/*the preferred priority*/) //with cdi 1.1+/ee7+
> public class SynchronizingTransactionStrategyDecorator implements
> TransactionStrategy {
> @Inject
> @Delegate
> private TransactionStrategy delegate;
>
> @Inject
> private SynchronizationBean synchronizationBean;
>
> @Override
> public Object execute(InvocationContext invocationContext) throws
> Exception {
> return synchronizationBean.executeSynchronized(delegate,
> invocationContext);
> }
> }
>
> SynchronizationBean is what you are trying to use.
> a possible method-signature for executeSynchronized:
> public Object executeSynchronized(TransactionStrategy
> transactionStrategy, InvocationContext invocationContext) throws Exception
> (do whatever you need to ensure the synchronization, but do it carefully to
> avoid deadlocks,... -> finally delegate via
> transactionStrategy.execute(invocationContext))
>
> regards,
> gerhard
>
>
>
> 2016-07-04 10:19 GMT+02:00 Xavier Dury <ka...@hotmail.com>:
>
>> Hi,
>>
>> I know that the EXTENDED PersistenceContext usage is not recommended by
>> the DeltaSpike team but I would like to have a discussion about it.
>>
>> I am currently developing a small-scale intranet application where our
>> core-business entity model has a lot of levels which can be lazily
>> expanded/collapsed in the UI (written in JSF). In this case, I really like
>> to be able to use an EXTENDED PersistenceContext and not really care about
>> eagerly loading all associations as, most of the time, deep levels won't
>> even be expanded (the decision is left to the user to expand what is
>> needed). And this is the concept that made me like Seam when it was first
>> released.
>>
>> Now, I have some concerns about the EntityManagerResolver:
>>
>> - As an EntityManagerResolver kinda "extracts" the EM from its owning
>> @Stateful bean, what guarantees do I have that this EM won't be used in
>> concurrent (AJAX) requests? If I am not mistaken, all method calls on a
>> @Stateful bean must be synchronized/locked but as the EM is not thread-safe
>> and won't be called in the context of a call on its owning SFSB, this could
>> be problematic. (Since JPA 2.1, I've seen a synchronization attribute on
>> @PersistenceContext but it has nothing to do with concurrent
>> synchronization.)
>>
>> - Correct me if I am wrong but the JEE spec does not (yet) define how an
>> EM that was "extracted" from its owning bean should behave.
>>
>> Therefore, wouldn't it be better to replace the EntityManagerResolver by
>> some sort of EntityManagerHolder like this one:
>>
>> public interface EntityManagerHolder {
>>
>> <T> T executeCallback(EntityManagerCallback<T> callback);
>> }
>>
>> public interface EntityManagerCallback<T> {
>>
>> T execute(EntityManager entityManager);
>> }
>>
>> and have it implemented like this:
>>
>> @Stateful
>> @TransactionManagement(BEAN) // TXs should not be handled here
>> @ViewScoped // for example
>> public class MyEntityManagerHolder implements EntityManagerHolder {
>>
>> @PersistenceContext(type = EXTENDED)
>> private EntityManager entityManager;
>>
>> public <T> T executeCallback(EntityManagerCallback<T> callback) {
>> return callback.execute(this.entityManager);
>> }
>> }
>>
>> Here, all calls on the EntityManager will happen inside a call on the SFSB
>> which should guarantee that only one thread at a time may use the EM and it
>> also circumvents the gap in the specification.
>>
>> What do you think? Is there something I forgot to take into account?
>>
>> Thanks,
>>
>> Regards,
>>
>> Xavier
 		 	   		  

Re: Some thoughts about EntityManagerResolver and EXTENDED PersistenceContext

Posted by Gerhard Petracek <gp...@apache.org>.
hi xavier,

if you are using @org.apache.deltaspike.jpa.api.transaction.Transactional,
you can use a decorator like:

@Decorator
@Priority(/*the preferred priority*/) //with cdi 1.1+/ee7+
public class SynchronizingTransactionStrategyDecorator implements
TransactionStrategy {
    @Inject
    @Delegate
    private TransactionStrategy delegate;

    @Inject
    private SynchronizationBean synchronizationBean;

    @Override
    public Object execute(InvocationContext invocationContext) throws
Exception {
        return synchronizationBean.executeSynchronized(delegate,
invocationContext);
    }
}

SynchronizationBean is what you are trying to use.
a possible method-signature for executeSynchronized:
  public Object executeSynchronized(TransactionStrategy
transactionStrategy, InvocationContext invocationContext) throws Exception
(do whatever you need to ensure the synchronization, but do it carefully to
avoid deadlocks,... -> finally delegate via
transactionStrategy.execute(invocationContext))

regards,
gerhard



2016-07-04 10:19 GMT+02:00 Xavier Dury <ka...@hotmail.com>:

> Hi,
>
> I know that the EXTENDED PersistenceContext usage is not recommended by
> the DeltaSpike team but I would like to have a discussion about it.
>
> I am currently developing a small-scale intranet application where our
> core-business entity model has a lot of levels which can be lazily
> expanded/collapsed in the UI (written in JSF). In this case, I really like
> to be able to use an EXTENDED PersistenceContext and not really care about
> eagerly loading all associations as, most of the time, deep levels won't
> even be expanded (the decision is left to the user to expand what is
> needed). And this is the concept that made me like Seam when it was first
> released.
>
> Now, I have some concerns about the EntityManagerResolver:
>
> - As an EntityManagerResolver kinda "extracts" the EM from its owning
> @Stateful bean, what guarantees do I have that this EM won't be used in
> concurrent (AJAX) requests? If I am not mistaken, all method calls on a
> @Stateful bean must be synchronized/locked but as the EM is not thread-safe
> and won't be called in the context of a call on its owning SFSB, this could
> be problematic. (Since JPA 2.1, I've seen a synchronization attribute on
> @PersistenceContext but it has nothing to do with concurrent
> synchronization.)
>
> - Correct me if I am wrong but the JEE spec does not (yet) define how an
> EM that was "extracted" from its owning bean should behave.
>
> Therefore, wouldn't it be better to replace the EntityManagerResolver by
> some sort of EntityManagerHolder like this one:
>
> public interface EntityManagerHolder {
>
>     <T> T executeCallback(EntityManagerCallback<T> callback);
> }
>
> public interface EntityManagerCallback<T> {
>
>     T execute(EntityManager entityManager);
> }
>
> and have it implemented like this:
>
> @Stateful
> @TransactionManagement(BEAN) // TXs should not be handled here
> @ViewScoped // for example
> public class MyEntityManagerHolder implements EntityManagerHolder {
>
>     @PersistenceContext(type = EXTENDED)
>     private EntityManager entityManager;
>
>     public <T> T executeCallback(EntityManagerCallback<T> callback) {
>         return callback.execute(this.entityManager);
>     }
> }
>
> Here, all calls on the EntityManager will happen inside a call on the SFSB
> which should guarantee that only one thread at a time may use the EM and it
> also circumvents the gap in the specification.
>
> What do you think? Is there something I forgot to take into account?
>
> Thanks,
>
> Regards,
>
> Xavier