title: Spring Data JPA - Lazy Loaded collection fetched without @Transactional
body: <p>My expectation is that a lazy loaded collection should be fetched when the collection is accessed within a transactional scope.  For example, if I want to fetch a collection I can call <code>foo.getBars.size()</code>.  The absence of an active transaction should result in an exception with an error message like</p>
  
  <blockquote>
    <p>failed to lazily initialize a collection of bars: .... could not
    initialize proxy - no Session</p>
  </blockquote>
  
  <p>However, I noticed that the behavior is different in my latest application.  I'm using Spring Boot 1.5.1 with the "data-jpa" starter. I have used Spring Boot in the past, but the data-jpa starter is new for me.</p>
  
  <p>Consider the following case.  I have a lazy loaded ManyToMany collection.</p>
  
  <pre><code>@SuppressWarnings("serial")
  @Entity
  @Table(name = "foo")
  public class Foo implements java.io.Serializable {
      ....
      private Set&lt;Bar&gt; bars = new HashSet&lt;Bar&gt;(0);
      ....
  
      @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
      @JoinTable(name = "foo_bar_map",
          joinColumns = {@JoinColumn(name = "foo_id", nullable = false, updatable = false)},
          inverseJoinColumns = {@JoinColumn(name = "bar_id", nullable = false, updatable = false)})
      public Set&lt;Bar&gt; getBars() {
          return this.bars;
      }
  
      public void setBar(Set&lt;Bar&gt; bars) {
          this.bars = bars;
      }
  </code></pre>
  
  <p>My service method is NOT marked as Transactional but I am accessing a lazy loaded collection</p>
  
  <pre><code>@Service
  public class FooServiceImpl implements FooService {
  
      @Autowired
      private FooRepository fooRepo;
  
  
      @Override
      public FooDTO findById(int fooId) {
          Foo foo = fooRepo.findOne(fooId);
          // The FooDTO constructor will access foo.getBars()  
          return new FooDTO(foo);
      }
  </code></pre>
  
  <p>And for context on the FooDTO constructor</p>
  
  <pre><code>public FooDTO(Foo foo) {
      ...
      for (Bar bar : foo.getBars()) {
          this.bars.add(bar);
      }
  }
  </code></pre>
  
  <p>Contrary to my expectation and past experience, this code executes successfully and fetches the collection.  Further, if I throw a breakpoint in my service method, I can step through the code and see the SQL statements in my logs that fetch the bars after my call to the fooRepo. After my call to fooRepo, I expect the transaction to be closed.</p>
  
  <p>What's happening here?  </p>