title: Spring Boot and fetchType=Lazy
body: <p>I have a problem with lazy initialization in my Spring Boot application. I have an entity with lazy field <code>Role</code>, and I they have <code>LazyInitializationException</code> in My Spring Security (<code>UserDetailsService</code>) method, but in controller it's ok.
  Can you explaine to me how Spring Boot works with <code>fetch = FetchType.LAZY</code> ? Why it does not work Spring Security <code>UserDetailsService</code> and work in controller methods?
  I did not find any guide about this. Thanks!</p>
  
  <p>Spring Boot :</p>
  
  <pre><code>@SpringBootApplication
  public class App {
  
      public static void main(String[] args) throws Exception {
          SpringApplication.run(App.class, args);
      }
  }
  </code></pre>
  
  <p>An Entity:</p>
  
  <pre><code>@Entity
  @Table(name = "users")
  @Getter
  @Setter
  @NoArgsConstructor
  public class Users {
      @ManyToMany(fetch = FetchType.LAZY)
      @JoinTable(name = "Users_Role", joinColumns = @JoinColumn(name = "User_id", referencedColumnName = "id"),
              inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
      private Set&lt;Role&gt; roles = new HashSet&lt;Role&gt;();
  }
  </code></pre>
  
  <p>My Service:   </p>
  
  <pre><code>@Transactional(readOnly = true)//does not matter
   public Users getUserByLogin(String login) {
          return usersRepository.findOneByLogin(login);
      }
  
      @Transactional(readOnly = true)
      public Users getUserByLoginWithRoles(String login) {
          Users oneByLogin = usersRepository.findOneByLogin(login);
          logger.debug("User was initialize with Roles: " + oneByLogin.getRoles().size()); // force initialize of roles and it works!
          return oneByLogin;
      }
  
     @Transactional(readOnly = true)//does not matter
      public Users testGetUser() {
          Users oneByLogin = usersRepository.getOne(1L);
          return oneByLogin;
      }
  
      @Transactional(readOnly = true)//does not matter
      public Users testFindUser() {
          Users oneByLogin = usersRepository.findOne(1L);
          return oneByLogin;
      }
  </code></pre>
  
  <p>And I have Spring Security UserDetailsService:</p>
  
  <pre><code>@Service
      public class UserDetailsServiceImpl implements UserDetailsService {
  
      @Autowired
      private Services services;
  
      @Override
      public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
          Users user;
          Users userFetchedViaGet = services.testGetUser();
          Users userFetchedViaCustomMethod = services.getUserByLogin(login);
          Users userFetchedViaFind = services.testFindUser();
          Users userFetchedWithRoles = services.getUserByLoginWithRoles(login);
          try {
              userFetchedViaGet.getRoles().add(new Role("test"));
          } catch (Exception e) {
              e.printStackTrace();//LazyInitializationException: failed to lazily initialize a collection of role: , could not initialize proxy - no Session
          }
          try {
              userFetchedViaCustomMethod.getRoles().add(new Role("test"));
          } catch (Exception e) {
              e.printStackTrace();//LazyInitializationException: failed to lazily initialize a collection of role: , could not initialize proxy - no Session
          }
          try {
              userFetchedViaFind.getRoles().add(new Role("test")); //LazyInitializationException: failed to lazily initialize a collection of role: , could not initialize proxy - no Session
          } catch (Exception e) {
              e.printStackTrace();
          }
          //some code
          }
      }
  </code></pre>
  
  <p>And My Controller (All methods works! But there is have to excpetion happen, because there is no session and Lazy fetch type):  </p>
  
  <pre><code>@RequestMapping(value = "/test", method = RequestMethod.GET)
      public String test() {      
          Users userFetchedViaGet = services.testGetUser();
          Users userFetchedViaCustomMethod = services.getUserByLogin("ADMIN");
          Users userFetchedViaFind = services.testFindUser();
          Users userFetchedWithRoles = services.getUserByLoginWithRoles("ADMIN");
          try {
              userFetchedViaGet.getRoles().add(new Role("test"));
          } catch (Exception e) {
              e.printStackTrace();
          }
          try {
              userFetchedViaCustomMethod.getRoles().add(new Role("test"));
          } catch (Exception e) {
              e.printStackTrace();
          }
          try {
              userFetchedViaFind.getRoles().add(new Role("test"));
          } catch (Exception e) {
              e.printStackTrace();
          }
          //some code
      }
  </code></pre>