"bfo81" wrote :
| Seam Managed Persistence Context
| I must confess that I never ran into LazyInitializationExceptions (abbr. LIE). I use
an Extended Persistence Context in a Conversation scoped Stateful Session Bean. And when
accessing related entities the EntityManager lazily fetches them without complaint.
Don't ask me why. Maybe you can add a case where the LIE occurs.
|
There is a 'subtle' difference between an extended persistence context (EPC) and
the seam managed persistence context (SMPC).
The EPC allows a conversational component's entity manager to manage the entities in a
'long running' transaction. The length of the transaction is usually scoped to
the lifespan of the component (typically a stateful session bean).
Lets assume we have the following entity relationship:
Customer 1 ------ * Address
.. and that the addresses are lazily loaded.
| @Stateful
| public class EditCustomerBean implements EditCustomer {
|
| @PersistenceContext(type=PersistenceContextType.EXTENDED)
| private EntityManager em;
|
| private Customer customer;
|
| @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
| public void init(long customerId) {
| customer = em.find(Customer.class, customerId);
| }
|
| @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
| public void addAddress(Address address) {
| customer.addAddress(address);
| }
|
|
| @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
| public Customer getCustomer() {
| return customer;
| }
|
| @Remove
| public void end() {
| em.flush();
| }
| }
|
Prior to ejb3 EPM's transactions typically spanned the remote method call (if your
methods were invoked in a JTA tx) - and the Customer object would therefore become
DETACHED at the end of the init() method. Calling addAddress() would then result in a LIE
as the Customer object is not associated with the current (new) transaction.
The lifespan of the EPC entity manager however is extended and therefore spans the
lifespan of the stateful session bean (sort of). So in the code snippet above, a client
could call init() and then addAddress() without having to rely on some re-initialisation
of the state of the customer on the second call (usually from some saved state detached
state stored in the bean).
Now the important part - Assuming the addresses are lazily loaded - If a (remote) client
calls init() and then getCustomer() and attempts to access the addresses outside the scope
of the entity manager - you will get a LIE whether the EntityManager is extended or not.
This is fairly intuitive - the Customer object has left the managed environment of the
stateful session bean and is no longer associated with the EPC.
The SMPC takes the concept of an EPC a little further by integrating the JSF lifecycle
with that of the stateful component. Effectively what the SMPC achieves is the removal of
LIE when traversing objects outside the scope of your session bean (there's more to it
than that - but for now that will do). So in your JSF, if you traversed the customer
--> addresses relationship (after outjecting a customer object) you'll avoid the
LIE issue.
For more information on EPC and application transactions see
http://docs.jboss.org/ejb3/app-server/tutorial/index.html
My experience with using an EPC is still somewhat new - and there are a few gotchas - like
marking methods as TX.NOT_SUPPORTED when you don't want to flush at the end of the
method etc - so any corrections/contributions are welcome.
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3964409#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...