Note that there are some explanatory texts on larger screens.

plurals
  1. POLazyInitializationException in JPA and Hibernate
    primarykey
    data
    text
    <p>I know that this question has been ask numerous times here and across the internet and I have read through many of those answers but I still don't understand the proper way to solve this problem. I am experimenting with Spring MVC and JPA and every time I access a lazily loaded property I get a LazyInitializationException. </p> <p>Here is some of the code I am experimenting with:</p> <pre><code>@Repository public class MyDAO { private static final Logger logger = LoggerFactory.getLogger(MyDAO.class); @PersistenceContext private EntityManager em; @Transactional public void logDOI() { DOI myDOI = em.find(DOI.class, Long.valueOf(1)); // This line gives the expected output logger.info("Fetched DOI: " + myDOI.getDoiKey()); // This line throws the LazyInitalizationException for(DOIMembership m : myDOI.getDoiMemberships()) { logger.info("Got DOI Membership id: " + m.getId()); } } } </code></pre> <p>The entity I am accessing:</p> <pre><code>@Entity @Table(name="DOI") public class DOI implements Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name="DOI_ID_GENERATOR", sequenceName="DOI_SEQ") @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="DOI_ID_GENERATOR") private long id; // Other properties omitted //bi-directional many-to-one association to DOIMembership @OneToMany(mappedBy="doi", fetch=FetchType.LAZY) private Set&lt;DOIMembership&gt; doiMemberships; public DOI() { } public long getId() { return this.id; } public void setId(long id) { this.id = id; } // Other Accessors Omitted } </code></pre> <p>The entity referenced from DOI</p> <pre><code>@Entity @Table(name="DOI_MEMBERSHIP") public class DOIMembership implements Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name="DOI_MEMBERSHIP_ID_GENERATOR", sequenceName="DOI_MEMBERSHIP_SEQ") @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="DOI_MEMBERSHIP_ID_GENERATOR") private long id; //bi-directional many-to-one association to DOI @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="DOI_ID") private DOI doi; @Column(name="GROUP_ID") private BigDecimal groupId; @Column(name="DATA_SET") private BigDecimal dataSetId; public DOIMembership() { } public BigDecimal getGroupId() { return groupId; } public BigDecimal getDataSetId() { return dataSetId; } public void setDataSetId(BigDecimal dataSetId) { this.dataSetId = dataSetId; } public void setGroupId(BigDecimal groupId) { this.groupId = groupId; } public long getId() { return this.id; } public void setId(long id) { this.id = id; } public DOI getDoi() { return this.doi; } public void setDoi(DOI doi) { this.doi = doi; } } </code></pre> <p>The Spring MVC Controller:</p> <pre><code>@Controller @RequestMapping("/summary") public class DOISummaryController { @Autowired MyDAO myDAO; @RequestMapping() public String DOISummary() { myDAO.logDOI(); return "home"; } } </code></pre> <p>My Spring configuration:</p> <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"&gt; &lt;!-- Root Context: defines shared resources visible to all other web components --&gt; &lt;context:property-placeholder location="WEB-INF/spring/root-context.properties, WEB-INF/spring/datasource-context.properties" /&gt; &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt; &lt;property name="driverClassName"&gt; &lt;value&gt;oracle.jdbc.driver.OracleDriver&lt;/value&gt; &lt;/property&gt; &lt;property name="url"&gt; &lt;value&gt;${Url}&lt;/value&gt; &lt;/property&gt; &lt;property name="username"&gt; &lt;value&gt;${Username}&lt;/value&gt; &lt;/property&gt; &lt;property name="password"&gt; &lt;value&gt;${Password}&lt;/value&gt; &lt;/property&gt; &lt;/bean&gt; &lt;bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt; &lt;property name="dataSource" ref="dataSource" /&gt; &lt;property name="jpaVendorAdapter"&gt; &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /&gt; &lt;/property&gt; &lt;property name="packagesToScan" value="org.myorg.doi.domain" /&gt; &lt;property name="jpaProperties"&gt; &lt;props&gt; &lt;prop key="hibernate.dialect"&gt; org.hibernate.dialect.Oracle10gDialect &lt;/prop&gt; &lt;prop key="hibernate.max_fetch_depth"&gt;3&lt;/prop&gt; &lt;prop key="hibernate.jdbc.fetch_size"&gt;50&lt;/prop&gt; &lt;prop key="hibernate.jdbc.batch_size"&gt;10&lt;/prop&gt; &lt;prop key="hibernate.show_sql"&gt;true&lt;/prop&gt; &lt;/props&gt; &lt;/property&gt; &lt;/bean&gt; &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt; &lt;property name="entityManagerFactory" ref="emf" /&gt; &lt;/bean&gt; &lt;tx:annotation-driven transaction-manager="transactionManager" /&gt; &lt;context:annotation-config /&gt; &lt;task:annotation-driven /&gt; &lt;context:component-scan base-package="org.myorg.doi" /&gt; &lt;/beans&gt; </code></pre> <p>And a stack trace, as requested:</p> <pre><code>SEVERE: Servlet.service() for servlet [appServlet] in context with path [/DOI] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: could not initialize proxy - no Session] with root cause org.hibernate.LazyInitializationException: could not initialize proxy - no Session at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:430) at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:121) at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180) at org.myorg.doi.dao.MyDAO.logDOI(MyDAO.java:27) at org.myorg.doi.web.DOISummaryController.DOISummary(DOISummaryController.java:29) 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.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:116) at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:98) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) 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:680) </code></pre> <p>I you can see, I am trying to use pure JPA and only using Hibernate as a JPA provider.</p> <p>I understand that the exception is caused by the session being detached from the entity. But, I thought that wouldn't happen if we are currently in a transaction, which should be the case since the logDOI method is annotated with @Transactional.</p> <p>Of course, everything works perfectly if I change the FetchType to EAGER but it seems that I shouldn't have to do that.</p> <p>I am also aware of OpenEntityManagerInViewFilter but it seems that I shouldn't have to use that either if I keep all access to my entities in a DAO annotated with @Transactional (or through some other means that I'm not aware of).</p> <p>I think that I might be approaching this problem incorrectly but I don't know what the correct approach is. How is one supposed to effectively use lazily loaded properties?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload