title: Hibernate 4 -> 5 upgrade leads to LazyInitializationException
body: <p>I upgraded a project from Spring 4.3.9.RELEASE + Hibernate 4.3.11.Final to Spring Boot 2.1.4.RELEASE and Hibernate 5.3.9.Final. The queries are still working fine, but I'm getting <code>LazyInitializationException</code> with some <code>@OneToMany</code> class members.</p>
  
  <p>First I retrieve the object, which has a reference to a <code>@OneToMany</code> List, from the <code>@Transaction</code> service. The collection is returned to the controller, and from there it goes back to Spring to be serialized into a json. The controller has <code>@RestController</code>, so it knows what to do.</p>
  
  <p>In Spring 4.3.9.RELEASE + Hibernate 4.3.11.Final everything was fine, even though <code>OpenEntityManagerInView</code> wasn't enabled by configuration and the collection wasn't loaded with EAGER mode. But in Spring Boot 2.1.4.RELEASE and Hibernate 5.3.9.Final the same thing doesn't work anymore. I've tried enabling OEMIV, by setting <code>spring.jpa.open-in-view=true</code>, but even this doesn't seem to work or it's being overriden somewhere.</p>
  
  <p>If I enable EAGER loading mode for that collection, everything works fine.</p>
  
  <p>pom.xml</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
  &lt;/dependency&gt;
  
  @Entity
  @JsonSerialize(using = TemplateSerializer.class)
  public class Template implements Serializable {
  
      @Id
      @GeneratedValue
      private Long id;
  
      private String name;
  
      @ManyToOne
      private ObjFormat objFormat;
  
      @OneToOne
      @JoinColumn(name = "event_id")
      @OnDelete(action = OnDeleteAction.CASCADE)
      private Event event;
  
      @OneToMany
      @JoinColumn(name = "category_id")
      private List&lt;Category&gt; linkToCategories;
  </code></pre>
  
  <p>The problem is caused by field linkToCategories. If I configure    @OneToMany(fetch = FetchType.EAGER) everything works fine.</p>
  
  <p>Application configuration:</p>
  
  <pre><code>    @Bean
      public LocalSessionFactoryBean sessionFactory(DataSource dataSource) throws ClassNotFoundException {
          LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
          localSessionFactoryBean.setDataSource(dataSource);
                localSessionFactoryBean.setPackagesToScan("com.project.backend.model",
              "com.project.backend.hibernate.converters");
          return localSessionFactoryBean;
      }
  
      @Bean
      public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
          return new HibernateTransactionManager(sessionFactory);
      }
  </code></pre>
  
  <p>Later edit:
  After a lot of debugging, the difference between the old and the new Hibernate functionality is in the HibernateTransactionManager. In the method doGetTransaction(), in Hibernate 4 it finds the SessionHolder object when calling </p>
  
  <blockquote>
    <p>TransactionSynchronizationManager.getResource(getSessionFactory())</p>
  </blockquote>
  
  <p>while in Hibernate 5 it doesn't. </p>
  
  <blockquote>
  <pre><code>    SessionHolder sessionHolder =
              (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
      if (sessionHolder != null) {
          if (logger.isDebugEnabled()) {
              logger.debug("Found thread-bound Session [" + sessionHolder.getSession() + "] for Hibernate transaction");
          }
          txObject.setSessionHolder(sessionHolder);
      }
      else if (this.hibernateManagedSession) {
          try {
              Session session = this.sessionFactory.getCurrentSession();
              if (logger.isDebugEnabled()) {
                  logger.debug("Found Hibernate-managed Session [" + session + "] for Spring-managed transaction");
              }
              txObject.setExistingSession(session);
          }
          catch (HibernateException ex) {
              throw new DataAccessResourceFailureException(
                      "Could not obtain Hibernate-managed Session for Spring-managed transaction", ex);
          }
      }
  </code></pre>
  </blockquote>
  
  <p>In the method doBegin, a new session is created and set on the txObject for every request.</p>
  
  <pre><code>        if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
              Interceptor entityInterceptor = getEntityInterceptor();
              Session newSession = (entityInterceptor != null ?
                      getSessionFactory().withOptions().interceptor(entityInterceptor).openSession() :
                      getSessionFactory().openSession());
              if (logger.isDebugEnabled()) {
                  logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");
              }
              txObject.setSession(newSession);
          }
  </code></pre>
  
  <p>My experience with Hibernate is fairly small, so here I'm stuck. It's probably a configuration thing, but I can't find it.</p>