Hi @all,

I know that this issue has been posted a bunch of times before, thus before of asking I was googling and searching in this forum for this topic without success in terms of finding something useful for solving my issue. I have decided to ask because probably my problem is due to a configuration mistake that I am not able to realize by myself.

So this is my scenario: Spring MVC 3, Spring Web Flow 2, JPA 2, Hibernate 3 and Spring Data. I use both MVC and SWF depending on the functionality, there are some complex wizards that with SWF are easier to implement. I am also using the AOP Spring's transactions manager.

This is my configuration:

  • In the web.xml file I am trying to set up the OpenEntityManagerInViewFilter so as I have read this is the filter to use for implementing the open session in view pattern:

Code:
	
	<filter>
		<filter-name>oemInViewFilter</filter-name>
		<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
		<init-param>
			<param-name>entityManagerFactoryBeanName</param-name>
			<param-value>entityManagerFactory</param-value>
		</init-param>
	</filter>
	
	<filter-mapping>
		<filter-name>oemInViewFilter</filter-name>
		<url-pattern>/</url-pattern>
	</filter-mapping>
  • At the same time, in dispatcher-servlet.xml I am setting up the PersistenceContext in flowScope:

Code:
	<flow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
		<flow:flow-execution-listeners>
			<flow:listener ref="jpaFlowExecutionListener" />
		</flow:flow-execution-listeners>
	</flow:flow-executor>
	
	<bean id="jpaFlowExecutionListener" class="org.springframework.webflow.persistence.JpaFlowExecutionListener">
		<constructor-arg ref="entityManagerFactory" />
		<constructor-arg ref="transactionManager" />
	</bean>
  • Transaction management is configured this way:

Code:
	<!-- To conduct transactions, we declare a JPA transaction manager that collaborates with the JPA EntityManager produced by the factory -->
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<!-- Reference to the entity manager factory defined in dal-context.xml -->
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
	
	<!-- Declaration of an AOP advice that defines transactional policies (beans that should be advised), referencing the transaction manager previously declared -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="find*(..)" propagation="SUPPORTS" isolation="DEFAULT" read-only="true" />
			<tx:method name="save*(..)" propagation="REQUIRED" isolation="DEFAULT" />
			<tx:method name="delete*(..)" propagation="REQUIRED" isolation="DEFAULT" />
			<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" />
		</tx:attributes>
	</tx:advice>
	
	<!-- Definition of the pointcut for the previously declared advice by using and AspectJ expression -->
	<aop:config>
		<!-- AspectJ pointcut expression -->
		<aop:pointcut id="blPointCut" expression="execution(public * ie.i2e2.greenmode.bl.bo.impl.*.*(..))" />
		<!-- Maps the pointcut to the transaction's advice -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="blPointCut" />
	</aop:config>
  • And finally, database access and entity manager factory are configured like this;

Code:
	<!-- JDBC based datasource definition (TODO: should be changed to JNDI datasource) -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
		<property name="url" value="jdbc:hsqldb:mem:gmtest" />
		<property name="username" value="sa" />
		<property name="password" value="" />
	</bean>
	
	<!-- Provide specifics about the particular JPA implementation to use, in this case Hibernate -->
	<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
		<property name="database" value="HSQL" />
		<property name="showSql" value="false"/>
		<property name="generateDdl" value="true"/>
		<property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
	</bean>
	
	<!-- Configuration of a JPA container-managed entity manager, wired with datasource and vendor adapter properties -->
	<bean id="entityManagerFactory" class= "org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<!-- Reference eto the previously defined datasource -->
		<property name="dataSource" ref="dataSource" />
		<!-- Reference eto the previously defined JPA vendor adapter -->
		<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
		<!-- Spring will try to automatically register DAO and domain objects to into a default persistence unit of JPA, acording to the value defined -->
		<property name="packagesToScan" value="ie.i2e2.greenmode.dal" />
	</bean>
	
	<!-- Adds an advisor to any bean that’s annotated with @Repository so that any platform-specific exceptions are caught and then rethrown as one of Spring’s unchecked data access exceptions -->
	<bean class="org.springframework.orm.hibernate3.HibernateExceptionTranslator"/>
FlowScoped PersistenceContext is working fine inside web flows, so I don't get a LazyInitializationException when calling lazy initialized objects. I would like to have the same behavior in pages rendered from a standard Spring MVC controller.

Isn't it working for me because I am mixing MVC and SWF? Or maybe the reason is that I am using a transaction manager instead of a the EntityManagerFactory directly, that is what the OpenEntityManagerInViewFilter requires for its initialization?

Lots of questions come to my mind and I am driving crazy trying to finde the proper way of configuring my scenario.

Any ideas?

Thanks in advance guys!