Announcement Announcement Module
Collapse
No announcement yet.
[spring + jpa] openEntityManagerInView and LazyInitializationException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • [spring + jpa] openEntityManagerInView and LazyInitializationException

    Hi,

    I have a problem with openEntityManagerInView.
    I have 2 entities and a oneToMany with fetchType.LAZY.
    Entity A < oneToMany > Entity B.

    Like a lot of people, i have a "LazyInitializationException".

    There are a lot of threads about it but i still didn't find a solution...

    Some threads or blog about openEntityManagerInView:
    http://forum.springsource.org/showthread.php?t=77300
    http://forum.springsource.org/showthread.php?t=90178
    http://forum.springsource.org/showthread.php?t=28935
    http://forum.springsource.org/showthread.php?t=33574
    http://blog.smartkey.co.uk/2010/03/o...rn-spring-jpa/
    ...

    I'm using Spring mvc + JPA (hibernate).
    Spring 3.0.3.release

    i can paste my pom.xml here if necessary.

    Log:
    Code:
    DEBUG: org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter - Using EntityManagerFactory 'entityManagerFactory' for OpenEntityManagerInViewFilter
    DEBUG: org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter - Opening JPA EntityManager in OpenEntityManagerInViewFilter
    avant la requete this.bibliService.getBibliotheques()
    DEBUG: org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation
    DEBUG: org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
    fin de la requête, appel à la JSP
    ERROR: org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: fr.acv.siec.testEnToutGenre.Bibliotheque.livre, no session or session was closed
    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: fr.acv.siec.testEnToutGenre.Bibliotheque.livre, no session or session was closed
    	[...]
    20 août 2010 09:14:54 org.apache.catalina.core.ApplicationDispatcher invoke
    GRAVE: "Servlet.service()" pour la servlet jsp a lancé une exception
    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: fr.acv.siec.testEnToutGenre.Bibliotheque.livre, no session or session was closed
    [...]
    DEBUG: org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter - Closing JPA EntityManager in OpenEntityManagerInViewFilter
    DEBUG: org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
    My web.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
    	<context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>
    			/WEB-INF/spring/*.xml
    		</param-value>
    	</context-param>
    	
    	<listener>
        	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
    	<filter>
            <filter-name>openEntityManagerInViewFilter</filter-name>
            <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>        
        </filter>
        
        <filter-mapping>
            <filter-name>openEntityManagerInViewFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        
       	<!-- Enables clean URLs with JSP views e.g. /welcome instead of /app/welcome -->
    	<filter>
    		<filter-name>UrlRewriteFilter</filter-name>
    		<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    	</filter>
    
    	<filter-mapping>
    		<filter-name>UrlRewriteFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>  
     
    	<!-- Handles all requests into the application -->
    	<servlet>
    		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>
    				/WEB-INF/spring/*.xml
    			</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    		
    	<!-- Maps all /app requests to the DispatcherServlet for handling -->
    	<servlet-mapping>
    		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    		<url-pattern>/app/*</url-pattern>
    	</servlet-mapping>
    		
    </web-app>
    - i try to move the OEMIV to the top, before the UrlRewriteFilter, after the UrlRewriteFilter without success...

    app-config.xml:
    Code:
    <!-- Scans within the base package of the application for @Components to configure as beans -->
    	<context:component-scan base-package="fr.acv.siec" />
    	<context:annotation-config />
    	<tx:annotation-driven />
    	
    	
    
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/test"/>
            <property name="username" value="myUsername"/>
            <property name="password" value="myPassword"/>
        </bean>
    	
    
    	  <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    		<property name="persistenceXmlLocations">
    			<list>
    				<value>classpath*:META-INF/persistence.xml</value>
    			</list>
    		</property>
    		<property name="dataSources">
    			<map>
    				<entry key="localDataSource" value-ref="dataSource" />
    			</map>
    		</property>
    		<property name="defaultDataSource" ref="dataSource" />
    	</bean>
    	
    	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    		p:dataSource-ref="dataSource"
    		p:persistenceUnitManager-ref="persistenceUnitManager">
    	</bean>
    
    	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
    		p:entityManagerFactory-ref="entityManagerFactory">
    		<property name="entityManagerFactory" ref="entityManagerFactory"/>
    	</bean>
    model - Bibliotheque.java:

    Code:
    @Entity
    @Table(name="test__bibli")
    public class Bibliotheque {
    	
    	@Id
    	@GeneratedValue(strategy=GenerationType.AUTO)
    	@Column(name="id")
    	public int getId() {
    		return id;
    	}
    	private int id;
    	public void setId(int id) {
    		this.id = id;
    	}
    	
    	@Column(name="name")
    	public String getName() {
    		return name;
    	}
    	private String name;
    	public void setName(String name) {
    		this.name = name;
    	}
    	
    	@OneToMany(mappedBy="bibli",fetch=FetchType.LAZY)
    	public Set<Livre> getLivre() {
    		return livre;
    	}
    	private Set<Livre> livre = new HashSet<Livre>();
    	public void setLivre(Set<Livre> livre) {
    		this.livre = livre;
    	}
    }
    Livre.java:
    Code:
    @Entity
    @Table(name="test__livre")
    public class Livre {
    	
    	@Id
    	@GeneratedValue(strategy=GenerationType.AUTO)
    	@Column(name="id")
    	public int getId() {
    		return id;
    	}
    	private int id;
    	public void setId(int id) {
    		this.id = id;
    	}
    	
    	@Column(name="name")
    	public String getName() {
    		return name;
    	}
    	private String name;
    	public void setName(String name) {
    		this.name = name;
    	}
    	
    	@ManyToOne(fetch=FetchType.LAZY)
    	@JoinColumn(name="bibli")
    	public Bibliotheque getBibli() {
    		return bibli;
    	}
    	private Bibliotheque bibli;
    	public void setBibli(Bibliotheque bibli) {
    		this.bibli = bibli;
    	}
    }
    DAO:
    Code:
    @Repository
    //@Transactional(readOnly = true)
    public class TestDaoImpl implements TestDao {
    	
    
    	@PersistenceContext
    	public void setEm(EntityManager em) {
    		this.em = em;
    	}
    	
    	private EntityManager em;
    	
    	public EntityManager getEm() {
    		return em;
    	}
    	
    	@SuppressWarnings("unchecked")
    	public List<Bibliotheque> getBibliotheques() {
    		return this.em.createQuery("SELECT b FROM Bibliotheque b").getResultList();
    	}
    
    	[...]
    }
    - i try with @PersistenceContext(type=PersistenceContextType.EX TENDED) and it works but the data are never refresh. And i'm sure it's not the solution for openEntityManagerInView

    service:
    Code:
    @Service
    public class BibliServiceImpl implements BibliService {
    
    	@Autowired
    	private TestDao dao;
    	
    	public List<Bibliotheque> getBibliotheques() {
    		return this.dao.getBibliotheques();
    	}
    
    	[...]
    }
    The method in my controller:
    I call my JSP with a list of "Bibliotheque".
    Code:
    @RequestMapping(method = RequestMethod.GET, value="/bibli.html")
    	public String bibli(Model model) {
    		System.out.println("avant la requete this.bibliService.getBibliotheques()");
    		model.addAttribute("listBibli", this.bibliService.getBibliotheques());
    		System.out.println("fin de la requête, appel à la JSP");
    		return "test/bibli";
    	}
    and the JSP:
    I print my list of "Bibliotheque", and for each items i want to print the list of "Livre". It's just an example to use LAZY.
    Code:
    <c:forEach var="bibli" items="${listBibli}">
    		<p>
    			${bibli.name }
    		</p>
    		 <c:forEach items="${bibli.livre}" var="livre">
    		 	${livre.name }<br />
    		 </c:forEach>
    		 
    	</c:forEach>
    i hope anyone can help me !
    Thank you for reading.

    Rorix.
    Last edited by rorix; Aug 20th, 2010, 08:53 AM. Reason: solved

  • #2
    You are loading the same configuration in your ContextLoaderListener (which the OpenEntityManagerInView uses) and in your DispatcherServlet, which basically renders your Filter useless.

    The ContextLoaderListener should load all generic functionality (services, infrastructure etc), the dispatcherservlet should load only web related things (views, handlers, etc).

    Comment


    • #3
      it works !
      Thank you very much

      This is the solution:

      web.xml
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      
      	<context-param>
      		<param-name>contextConfigLocation</param-name>
      		<param-value>
      			/WEB-INF/spring/app-context.xml
      		</param-value>
      	</context-param>
      	
      	<listener>
          	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>
      
      
      
      	<filter>
              <filter-name>openEntityManagerInViewFilter</filter-name>
              <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>        
          </filter>
          
          <filter-mapping>
              <filter-name>openEntityManagerInViewFilter</filter-name>
              <url-pattern>/*</url-pattern>
          </filter-mapping>
          
         	<!-- Enables clean URLs with JSP views e.g. /welcome instead of /app/welcome -->
      	<filter>
      		<filter-name>UrlRewriteFilter</filter-name>
      		<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
      	</filter>
      
      	<filter-mapping>
      		<filter-name>UrlRewriteFilter</filter-name>
      		<url-pattern>/*</url-pattern>
      	</filter-mapping>  
           <!--
           <filter>
              <filter-name>openEntityManagerInViewFilter</filter-name>
              <filter-class>fr.acv.siec.testEnToutGenre.HibernateOpenSessionFilter</filter-class>
          </filter>
          
          <filter-mapping>
              <filter-name>openEntityManagerInViewFilter</filter-name>
              <url-pattern>/*</url-pattern>
          </filter-mapping>
          -->
       
      	<!-- Handles all requests into the application -->
      	<servlet>
      		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
      		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      		<init-param>
      			<param-name>contextConfigLocation</param-name>
      			<param-value>
      				/WEB-INF/spring/dispatcher-config.xml
      			</param-value>
      		</init-param>
      		<load-on-startup>1</load-on-startup>
      	</servlet>
      		
      	<!-- Maps all /app requests to the DispatcherServlet for handling -->
      	<servlet-mapping>
      		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
      		<url-pattern>/app/*</url-pattern>
      	</servlet-mapping>
      </web-app>
      app-context.xml
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
      	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
      	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
                                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
                                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
      						  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"
      	xmlns:jee="http://www.springframework.org/schema/jee"
      	xmlns:aop="http://www.springframework.org/schema/aop">
      	
      
      	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
              <property name="url" value="jdbc:mysql://localhost:3306/test"/>
              <property name="username" value="test"/>
              <property name="password" value=""/>
          </bean>
      	
      
      	  <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
      		<property name="persistenceXmlLocations">
      			<list>
      				<value>classpath*:META-INF/persistence.xml</value>
      			</list>
      		</property>
      		<property name="dataSources">
      			<map>
      				<entry key="localDataSource" value-ref="dataSource" />
      			</map>
      		</property>
      		<property name="defaultDataSource" ref="dataSource" />
      	</bean>
      	
      	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      		p:dataSource-ref="dataSource"
      		p:persistenceUnitManager-ref="persistenceUnitManager">
      	</bean>
      
      	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
      		p:entityManagerFactory-ref="entityManagerFactory">
      		<property name="entityManagerFactory" ref="entityManagerFactory"/>
      	</bean>
      
      </beans>
      dispatcher-config.xml
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xmlns:mvc="http://www.springframework.org/schema/mvc"
      	xmlns:context="http://www.springframework.org/schema/context"
      	xmlns:tx="http://www.springframework.org/schema/tx"
      	xsi:schemaLocation="
      		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
      		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
      		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
      
      	<!-- Scans within the base package of the application for @Components to configure as beans -->
      	<context:component-scan base-package="fr.acv.siec" />
      	<context:annotation-config />
      	<tx:annotation-driven />
      
      	<!-- Configures support for @Controllers -->
      	<mvc:annotation-driven />
      	
      	<!-- Configures Handler Interceptors -->	
      	<mvc:interceptors>
      		<!-- Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de -->
      		<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
      	</mvc:interceptors>
      
      	<!-- Saves a locale change using a cookie -->
      	<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />
      
      	<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
      	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      		<property name="prefix" value="/WEB-INF/views/"/>
      		<property name="suffix" value=".jsp"/>
      	</bean>
      	
      	<!-- ================================= GESTION DES LANGUES ================================== -->
      	
      
      	<bean id="messageSource"
      	      class="org.springframework.context.support.ResourceBundleMessageSource">
      	  <property name="basenames">
      	    <list>
      	      <value>fr.acv.siec.messages.siecmessage</value>
      	    </list>
      	  </property>
      	</bean>	
      	
      	<!-- Enregistrement de fichier (import) -->
      	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      	    <property name="maxUploadSize" value="100000"/>
      	</bean>
      	
      </beans>

      Comment

      Working...
      X