[jboss-user] [JBoss Seam] - Re: EntityManager: For newbies or to close gaps in your know
justinwalsh
do-not-reply at jboss.com
Thu Aug 10 11:35:21 EDT 2006
"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#3964409
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3964409
More information about the jboss-user
mailing list