I am currently trying to integrate the "open-session-in-view" pattern in my 
project (tapestry4 + ejb3).

Both technologies are great, but I get this LazyInitializationException, you 
know what I mean.

Inspired by the Seam-approach I tried to do something similar using tapestry 
instead of jsf.

My main problem is the handling of "injected" EntityManagers.

EntityManager of type "EXTENDED" are only inherited to other @EJB resources 
within a JTA-transaction.

For my understanding the "open-session-in-view" does not need a transaction at 
all,
just a open session (=> HibernateSession = EntityManager(EXTENDED)) to prevent 
the LazyInitializationException.

But calling an EJB (having a PersistenceContext.TRANSACTION) in the weblayer 
without having a JTA-transaction returns detached Entities.

This is correct according to the EJB 3 spec, so I thought about a solution by 
using an @Interceptor.


public class ThreadedEntityManagerInterceptor
  | {
  |     private final static ThreadLocal<EntityManager> THREADED_ENTITY_MANAGER 
= new ThreadLocal<EntityManager>();
  |     
  |     public synchronized static void setEntityManager(EntityManager eMgr)
  |     {
  |         THREADED_ENTITY_MANAGER.set(eMgr);
  |     }
  |     
  |     @AroundInvoke
  |     public Object injectEntityManager(InvocationContext ctx) throws 
Exception
  |     {
  |         if(THREADED_ENTITY_MANAGER.get() == null)
  |         {
  |             return ctx.proceed();
  |         }
  | 
  |         Class cls = ctx.getBean().getClass();
  |         
  |         for(Field f : cls.getDeclaredFields())
  |         {
  |             if(EntityManager.class.isAssignableFrom(f.getType()))
  |             {
  |                 if(f.isAnnotationPresent(PersistenceContext.class))
  |                     continue;
  |                 
  |                 if(f.get(ctx.getBean()) == null)
  |                     f.set(ctx.getBean(), THREADED_ENTITY_MANAGER.get());
  |             }
  |         }
  |         
  |         return ctx.proceed();
  |     }
  | }

"setEntityManager" will be called by a servlet-filter before any EJB is 
referenced.

The filter passes in a EntityManager(PersistenceContext.EXTENDED) of a 
@Stateful session-bean.

This should work in my opinion.

But calling a method on a EntityManager which is setted by the above 
@Intercepter results in the following exception:

Caused by: java.lang.NullPointerException
  |         at 
org.jboss.ejb3.entity.ExtendedEntityManager.getPersistenceContext(ExtendedEntityManager.java:59)
  |         at 
org.jboss.ejb3.entity.ExtendedEntityManager.find(ExtendedEntityManager.java:114)
  |         at 
de.jitek.component.friendler.EntityServiceBean.findByPrimaryKey(EntityServiceBean.java:32)
  |         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  |         at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  |         at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  |         at java.lang.reflect.Method.invoke(Method.java:585)
  |         at 
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:109)
  |         at 
org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:168)
  |         at 
de.jitek.component.friendler.ThreadedEntityManagerInterceptor.injectEntityManager(ThreadedEntityManagerInterceptor.java:57)
  |         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  |         at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  |         at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  |         at java.lang.reflect.Method.invoke(Method.java:585)
  |         at 
org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:120)
  |         at 
org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:62)
  |         at 
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
  |         at 
org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
  |         at 
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
  |         at 
org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)        
        
Would be great if someone could explain why this happen and how to solve the 
problem.

Is it possible at all, what I am trying to do or is there already an existing 
solution of the LazyInitializationException (tapestry + ejb3) ?


Any help would very appreciated.

Regards,
Jan

View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3928582#3928582

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3928582


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
JBoss-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jboss-user

Reply via email to