Problem integrating Seam 2 into Spring 2.5 application
marvm Apr 3, 2008 6:33 PMHello,
I try to integrate Seam into my Spring 2.5 based project.
I am using the latest JBosss but due to some time issues I do not want to reprogram my DAOs to some session beans, so the database access should be covered still by my DAOs.
As persistence provider I chose Hibernate 3.2. After programming some pages with jsf and seam components I ran into the problem of getting LazyInitializationExceptions. I figured out that the problem is caused by spring. I tried to make an entity available during a long running conversation. After retrieving it from the database and rendering the first page the instance is detached, because the spring transaction finished, which is normal.
Now I get the exception when I request the next page which refers to a lazy-loaded set of my object from the conversation scope.
I thought ok, let's see what seam is offering me as a solution and found the magic seam managed persistence context! And now I am totally frustrated getting this into my application... ;)
Ok, maybe my current, not working configuration says more:
components.xml:
<core:manager conversation-timeout="120000" concurrent-request-timeout="500" conversation-id-parameter="cid"/> <persistence:managed-persistence-context name="entityManager" auto-create="true" entity-manager-factory="#{entityManagerFactory}" /> <!-- Configuration of Hibernate Session --> <persistence:hibernate-session-factory></persistence:hibernate-session-factory> <persistence:managed-hibernate-session name="hibernateSession" auto-create="true" /> <core:init debug="true"/> <spring:context-loader config-locations="/WEB-INF/applicationContext.xml"/> <!-- Install the SpringDispatcher as default --> <spring:task-executor-dispatcher schedule-dispatcher="#{threadPoolDispatcher}" task-executor="#{springThreadPoolTaskExecutor}"/> <spring:spring-transaction platform-transaction-manager="#{transactionManager}"/> </components>
application-context.xml
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"><value>${dataSource.driverClassName}</value></property> <property name="url"><value>${dataSource.url}</value></property> <property name="username"><value>${dataSource.username}</value></property> <property name="password"><value>${dataSource.password}</value></property> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="persistenceUnitName" value="myDb"/> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean> <tx:annotation-driven proxy-target-class="true" /> <!-- EMF that wraps a Seam Managed EM instance for use in Spring --> <bean id="seamEntityManagerFactory" class="org.jboss.seam.ioc.spring.SeamManagedEntityManagerFactoryBean"> <!-- The Seam managed-persistence-context component name. --> <property name="persistenceContextName" value="entityManager" /> <!-- Optionally provide a unit name. If not specified the default would be the persistenceContextName --> <property name="persistenceUnitName" value="myDb"/> </bean> <bean id="sessionFactory" class="org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean"> <property name="sessionName" value="hibernateSession"/> </bean>
hibernate.cfg.xml
<hibernate-configuration> <session-factory name="java:/hibernateSessionFactory"> <property name="dataSource">java:/PofProjectDbDS</property> <property name="hibernate.dialect"> org.hibernate.dialect.SQLServerDialect </property> <property name="transaction.flush_before_completion"> true </property> <property name="connection.release_mode"> after_statement </property> <property name="transaction.manager_lookup_class"> org.hibernate.transaction.JBossTransactionManagerLookup </property> <property name="transaction.factory_class"> org.hibernate.transaction.JTATransactionFactory </property> <mapping package="com.project.model" /> <mapping class="com.project.model.Person" />
well, I tried everything to make it work, so some options are doubled now...
persistence.xml
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="myDb" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/MyProjectDS</jta-data-source> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/> <property name="transaction.flush_before_completion" value="true" /> <property name="connection.release_mode" value="after_statement" /> <property name="transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" /> <property name="transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" /> </properties> </persistence-unit>
My application starts normally, everything seems to be mapped correctly, but when I send the first request to the application I get the following exception:
Caused by: java.lang.IllegalAccessException: Class org.jboss.seam.util.Reflections can not access a member of class org.springframework.beans.factory.config.AbstractFactoryBean with modifiers "protected" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65) at java.lang.reflect.Method.invoke(Method.java:588) at org.jboss.seam.util.Reflections.invoke(Reflections.java:21) at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56) at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:31) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106) at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:155) at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:91) at org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean_$$_javassist_0.getEarlySingletonInterfaces(SeamManagedSessionFactoryBean_$$_javassist_0.java) at org.springframework.beans.factory.config.AbstractFactoryBean.getEarlySingletonInstance(AbstractFactoryBean.java:145) at org.springframework.beans.factory.config.AbstractFactoryBean.getObject(AbstractFactoryBean.java:133) at org.springframework.beans.factory.support.AbstractBeanFactory$3.run(AbstractBeanFactory.java:1304) ... 201 more
When I try to solve that problem by making my sessionFactory a seam component I get another exception:
java.lang.IllegalStateException: Seam application context not available and cannot be started. Seam Managed Persistence Context not available. Try placing the spring bean call inside of a spring transaction or try making the spring bean a Seam Component using <seam:component/>. at org.jboss.seam.ioc.spring.SeamLifecycleUtils.beginTransactionalSeamCall(SeamLifecycleUtils.java:44) at org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean$SeamManagedSessionFactoryHandler.getSession(SeamManagedSessionFactoryBean.java:129) at org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean$SeamManagedSessionFactoryHandler.getRawSessionFactory(SeamManagedSessionFactoryBean.java:122) at org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean$SeamManagedSessionFactoryHandler.invoke(SeamManagedSessionFactoryBean.java:145)
<bean id="sessionFactory" class="org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean"> <property name="sessionName" value="hibernateSession"/> <seam:component /> </bean>
Does anybody have some help?
Thanks in advance...