Matthias Wuttke
Matthias Wuttke

Reputation: 2032

LazyInitializationException (Spring and Vaadin) despite of OpenEntityManagerInView

I am using Spring Roo and Vaadin for a (simple) database application. There is a view displaying a Table containing entities. For the table to be displayed, Hibernate needs to lazily load 1:n referenced entities. This works for small tables, but as soon as the table gets bigger, only the first part is displayed correctly, and the following exception occurs.

com.vaadin.data.util.MethodProperty$MethodException
    at com.vaadin.data.util.MethodProperty.getValue(MethodProperty.java:612)
    at com.vaadin.data.util.AbstractProperty.toString(AbstractProperty.java:78)
    at com.vaadin.ui.Table.formatPropertyValue(Table.java:3476)
    at eu.wuttke.tinyscrum.ui.dashboard.DashboardTaskStoryTable.formatPropertyValue(DashboardTaskStoryTable.java:66)
    at com.vaadin.ui.Table.getPropertyValue(Table.java:3428)
    at com.vaadin.ui.Table.getVisibleCellsNoCache(Table.java:1853)
    at com.vaadin.ui.Table.refreshRenderedCells(Table.java:1477)
    at com.vaadin.ui.Table.enableContentRefreshing(Table.java:2645)
    at com.vaadin.ui.Table.changeVariables(Table.java:2491)
    at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.changeVariables(AbstractCommunicationManager.java:1455)
    at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariableBurst(AbstractCommunicationManager.java:1399)
    at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariables(AbstractCommunicationManager.java:1318)
    at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:763)
    at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:296)
    at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:501)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:147)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
    at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
    at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:769)
    at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:698)
    at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:891)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
    at java.lang.Thread.run(Thread.java:679)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.GeneratedMethodAccessor841.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at com.vaadin.data.util.MethodProperty.getValue(MethodProperty.java:610)
    ... 34 more
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
    at eu.wuttke.tinyscrum.domain.Iteration_$$_javassist_1.getName(Iteration_$$_javassist_1.java)
    at eu.wuttke.tinyscrum.domain.Iteration_Roo_JavaBean.ajc$interMethodDispatch1$eu_wuttke_tinyscrum_domain_Iteration_Roo_JavaBean$eu_wuttke_tinyscrum_domain_Iteration$getName(Iteration_Roo_JavaBean.aj)
    at eu.wuttke.tinyscrum.domain.TaskAndStory.getIterationName(TaskAndStory.java:32)
    ... 38 more

I know this LazyInitializationException exception from other Hibernate applications, where it occurs when the session is not open or already closed again. But looking at the stack trace, it seems the OpenEntityManagerInView filter is getting called.

Any ideas? Thanks a lot!

Upvotes: 2

Views: 2674

Answers (1)

TRex
TRex

Reputation: 141

Vaadin has a persistent state on the server side. If you bind objects to Vaadin components (e.g. by using a BeanItemContainer) your objects will "live" for more then one request on the server side.

On the other hand Spring (via OpenEntityManagerInView) will create a new EntityManager for each request (EntityManagers are not threa safe) and close it after the request. This way your already loaded Entities will become detached (the EM is no longer avaiable), and when Vaadin makes a new request to e.g. load more table rows, the lazy loading fileds will not be able to load (and you will get the LazyInitializationException) since the EM that loaded them no longer exists.

Some solutions:

  • Use the Eager JPA Fetch (@ManyToOne (fetch= FetchType.EAGER))
  • Load you object with JOIN FETCH queries (e.g. SELECT mag FROM Magazine mag LEFT JOIN FETCH mag.articles WHERE mag.id = 1 See more)
  • Use EclipseLink (EclipseLink will open a new Session to load the lazy load fields for detached objects) [We are using this approach]

Upvotes: 8

Related Questions