title: Spring Hibernate Lazy Fetch collections transactions not working
body: <p>I am utterly confused, I have been creating my first Spring application with hibernate and I can not seem to spot my error when lazy loading objects from my database.</p>
  
  <p>My Models are as follows</p>
  
  <p><strong>The Team class</strong></p>
  
  <pre><code>@Entity
  public class Team {
  
      @Id
      @Column
      @GeneratedValue(strategy=GenerationType.AUTO)
      private int id;
      @Column
      private String name;
      @Column
      private String description;
  
      @OneToMany(fetch=FetchType.LAZY , cascade = CascadeType.ALL, mappedBy="team")
      @JsonIgnore
      public List&lt;Person&gt; members;
  
      //Constructors and setters getters ommited
  }
  </code></pre>
  
  <p><strong>The Person class</strong></p>
  
  <pre><code>@Entity
  @Table(name="`person`")
  public class Person {
  
      @Id
      @Column
      @GeneratedValue(strategy=GenerationType.AUTO)
      private int id;
      @Column
      private String name;
  
      @ManyToOne(fetch=FetchType.LAZY)
      @JoinColumn(name="team")
      @JsonIgnore
      private Team team;
  
      //omitted constructor and methods
  }
  </code></pre>
  
  <p>I then have My Data Access Objects which all follow the same pattern as this</p>
  
  <pre><code>@Repository
  public class TeamDaoImpl implements TeamDao {
  
      @Autowired
      private SessionFactory session;
  
      @Override
      public void add(Team team) {
          session.getCurrentSession().save(team);
      }
  
      @Override
      public void edit(Team team) {
          session.getCurrentSession().update(team);
      }
  
      @Override
      public void delete(int teamId) {
          session.getCurrentSession().delete(getTeam(teamId));
      }
  
      @Override
      public Team getTeam(int teamId) {
          return (Team) session.getCurrentSession().get(Team.class, teamId);
      }
  
      @Override
      public List getAllTeam() {
          return session.getCurrentSession().createQuery("from Team").list();
      }
  
  }
  </code></pre>
  
  <p>In all these methods I make sure to use the current session to perform these actions.  From my understanding this makes sure that it places these calls into the existing transaction which is create in the service class as follows:</p>
  
  <pre><code>@Service
  public class PersonServiceImpl implements PersonService {
  
      Logger log = Logger.getLogger(PersonServiceImpl.class);
  
      @Autowired
      PersonDao personDao;
  
      @Autowired
      TeamDao teamDao;
  
      //Ommitted other methods
  
      @Transactional
      public List getPeopleForTeam(int teamId) {
          log.info("Getting people for team with id " + teamId);
          Team team = teamDao.getTeam(teamId);
          return team.getMembers();
      }
  
  }
  </code></pre>
  
  <p>My understanding was that the <code>@Transactional</code> annotation should put that method into a single transaction.</p>
  
  <p>This all compiles fine but when I run it I get the following error</p>
  
  <pre><code>org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: model.Team.members, no session or session was closed; nested exception is 
  com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: model.Team.members, no session or session was closed
      org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.writeInternal(MappingJackson2HttpMessageConverter.java:207)     
  
  org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:179)    
  
  org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:148)  
  org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:90)   
  org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:189)     
  org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:69)     
  org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122)     
  org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)    
  org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)    
  org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)    
  org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)    
  org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)     
  org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)  
  org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)   
  javax.servlet.http.HttpServlet.service(HttpServlet.java:621)    
  org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)     
  javax.servlet.http.HttpServlet.service(HttpServlet.java:728)    
  org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
  </code></pre>
  
  <p>What am I doing wrong? Is my understanding of the @Transactional annotation incorrect?  If so how should I go about lazy loading collections inside the object yet fetching them within certain transactional methods?</p>
  
  <p>EDIT:</p>
  
  <p>This is the relevant part of my spring configuration </p>
  
  <pre><code>&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
          p:url="${jdbc.databaseuri}" p:username="${jdbc.username}"  /&gt;
  
  
  
   &lt;bean id="sessionFactory"
          class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
          &lt;property name="configLocation"&gt;
              &lt;value&gt;classpath:hibernate.cfg.xml&lt;/value&gt;
          &lt;/property&gt;
          &lt;property name="configurationClass"&gt;
              &lt;value&gt;org.hibernate.cfg.AnnotationConfiguration&lt;/value&gt;
          &lt;/property&gt;
          &lt;property name="hibernateProperties"&gt;
              &lt;props&gt;
                  &lt;prop key="hibernate.dialect"&gt;${jdbc.dialect}&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.hibernate3.HibernateTransactionManager"&gt;
              &lt;property name="dataSource" ref="dataSource" /&gt;
              &lt;property name="sessionFactory" ref="sessionFactory" /&gt; 
  &lt;/bean&gt;
  &lt;tx:annotation-driven transaction-manager="transactionManager" /&gt;
  </code></pre>
  
  <p>This is another part of the configuration</p>
  
  <pre><code>    &lt;mvc:annotation-driven&gt;
          &lt;mvc:message-converters&gt;
              &lt;!-- Use the HibernateAware mapper instead of the default --&gt;
              &lt;bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"&gt;
                  &lt;property name="objectMapper"&gt;
                      &lt;bean class="com.bt.opsscreens.mappers.HibernateAwareObjectMapper" /&gt;
                  &lt;/property&gt;
              &lt;/bean&gt;
          &lt;/mvc:message-converters&gt;
      &lt;/mvc:annotation-driven&gt;
  </code></pre>
  
  <p>This is the part of the controller</p>
  
  <pre><code>@RequestMapping(value="/{teamId}/people", method=RequestMethod.GET)
      public @ResponseBody List&lt;Person&gt; getPeopleForTeam(@PathVariable int teamId) {
          return personService.getPeopleForTeam(teamId);
      }
  </code></pre>