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