SEAM 3 Spring ExtendedpersitenceContext
stefrem Jan 17, 2012 9:19 AMHi,
I'm testing a technical stack with Spring 3.x / Seam 3.x / JPA 2.0 / JSF 2.x.
In my company, we've already a stack with Spring 2.5 / Seam 2.2 / Hibernate 3.3 / JSF 1.2 / Richfaces 3.3. We have choosen this stack to manage extended persistent context with seam long running conversation in Ui and Navigation layer and to manage transactions with spring in dao and service layers.
But my tests with new stack failed because I can't manage extended persistent context like old stack. I tried Seam-Spring module but with it CDI beans are imported as prototype spring bean, also I can't reproduce the hibernateSession created by Seam with conversation Scope and injected in Spring.
In old Stack, my config was :
In components.xml :
<persistence:managed-persistence-context name="entityManagerManaged" entity-manager-factory="#{springEntityManagerFactory}" auto-create="true" /> <factory name="hibernateSession" scope="STATELESS" auto-create="true" value="#{entityManagerManaged.delegate}"/>
In Spring applicationContext.xml :
<bean id="hibernateTemplateSeam" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="seamSessionFactory" /> <!-- Config pour le flush mode MANUAL/NEVER --> <property name="checkWriteOperations" value="false" /> </bean> <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="springEntityManagerFactory"> <property name="persistenceUnitName" value="persistenceUnitRedaction"/> <property name="persistenceXmlLocation" value="classpath:com/agysoft/marco/persistence-Jpa.xml" /> <property name="dataSource" ref="defaultDatasource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> </property> </bean> <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager"> <property name="entityManagerFactory" ref="springEntityManagerFactory"/> </bean> <!-- transaction --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- ====================== DATASOURCE DEFINITION ====================== --> <!-- Configuration de Seam Session Factory --> <bean id="seamSessionFactory" class="org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean"> <property name="sessionName" value="hibernateSession"/> </bean>
In new Stack, my config was :
A EMF Producer with:
@Inject @SpringContext ApplicationContext context; /* * The more eagle eyed among you may have noticed that the resource producer field appears to be conversation scoped, which the CDI specification does * not require containers to support. This is actually not the case, as the @ConversationScoped annotation is removed by the seam persistence portable * extension. It only specifies the scope of the created SMPC, not the EntityManagerFactory. */ @ExtensionManaged @Produces @ConversationScoped @PersistenceUnit public EntityManagerFactory getEntityManagerFactory() { return this.context.getBean("springEntityManagerFactory", EntityManagerFactory.class); }
In DAO, I don't know how I could inject CDI SMPC in my hibernateTemplate like in old stack.
Moreover with this config, an exception is triggered when I access to any JSF page because Seam-Faces start a transaction (I would use this feature to reproduce previous behavior of old stack):
java.lang.RuntimeException: java.lang.RuntimeException: Exception invoking method [markTransactionRollback] on object [org.jboss.seam.transaction.SimpleTransactionExceptionHandler@2c5f8a], using arguments [org.jboss.solder.exception.control.CaughtException@1347df0] at org.jboss.seam.faces.exception.CatchExceptionHandler.handle(CatchExceptionHandler.java:75) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119) at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:279) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Caused by: java.lang.RuntimeException: Exception invoking method [markTransactionRollback] on object [org.jboss.seam.transaction.SimpleTransactionExceptionHandler@2c5f8a], using arguments [org.jboss.solder.exception.control.CaughtException@1347df0] at org.jboss.solder.reflection.Reflections.invokeMethod(Reflections.java:480) at org.jboss.solder.reflection.Reflections.invokeMethod(Reflections.java:403) at org.jboss.solder.reflection.annotated.InjectableMethod.invoke(InjectableMethod.java:175) at org.jboss.solder.exception.control.HandlerMethodImpl.notify(HandlerMethodImpl.java:182) at org.jboss.solder.exception.control.ExceptionHandlerDispatch.executeHandlers(ExceptionHandlerDispatch.java:92) 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:597) at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:264) at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52) at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137) at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:260) at org.jboss.weld.introspector.jlr.WeldMethodImpl.invokeOnInstance(WeldMethodImpl.java:170) at org.jboss.weld.introspector.ForwardingWeldMethod.invokeOnInstance(ForwardingWeldMethod.java:51) at org.jboss.weld.injection.MethodInjectionPoint.invokeOnInstanceWithSpecialValue(MethodInjectionPoint.java:154) at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:241) at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:229) at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:207) at org.jboss.weld.manager.BeanManagerImpl.notifyObservers(BeanManagerImpl.java:569) at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:559) at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:554) at org.jboss.seam.faces.exception.CatchExceptionHandler.handle(CatchExceptionHandler.java:71) ... 19 more Caused by: org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.ConversationScoped at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:598) at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:71) at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:104) at org.jboss.weld.proxies.EntityManager$ManagedPersistenceContext$1229430268$Proxy$_$$_WeldClientProxy.getTransaction(EntityManager$ManagedPersistenceContext$1229430268$Proxy$_$$_WeldClientProxy.java) at org.jboss.seam.transaction.EntityTransaction.getDelegate(EntityTransaction.java:59) at org.jboss.seam.transaction.EntityTransaction.getStatus(EntityTransaction.java:108) at org.jboss.seam.transaction.EntityTransaction$Proxy$_$$_WeldClientProxy.getStatus(EntityTransaction$Proxy$_$$_WeldClientProxy.java) at org.jboss.seam.transaction.SimpleTransactionExceptionHandler.markTransactionRollback(SimpleTransactionExceptionHandler.java:47) 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:597) at org.jboss.solder.reflection.Reflections.invokeMethod(Reflections.java:474) ... 41 more
I try to desactivate faces Transaction with this config :
<sc:Veto> <s:Qualifier/> </sc:Veto> <ft:TransactionPhaseListener> <s:replaces/> <sc:Veto/> </ft:TransactionPhaseListener>
JSF page are displayed and I can call Spring service but SQL query are not commit automatically and long conversation don't work.
I saw this post :
SpringSeamManagedPersistentContextAndInjectionSpringCDI
and this entry in JIRA :
My question is quite simple :
Can we reproduce in my new stack the old behaviour of long running conversation with Spring to manage transactions in DAO and Service layers ?
If the answer is YES, where is my problem in my config above ?
Can you help me please, I would be very happy ;).
Specialy, if Marius Bogoevici could explain me why SEAMSpring5 feature request is mark Unresolved but added in SEAMSpring 3.1.0Final. This feature work or not ?
Thanks Stephane.