How to avoid the LazyInitializationException

As I started to work to a small project based on Spring MVC + JPA2/Hibernate + Rest, I faced this interesting exception which is known as LazyInitializationException.

Before we discuss about the exact error and the solution, let me show you what I did and I came up to face that issue.

As I said before I had a project which is using JPA2/Hibernate, so I provided some entities and daos in order to communicate and get data from my database.

For example I had the Table User(Getters/Setters are omitted):

@Entity
@Table(name="USER")
public class UserEntity implements Serializable {

  private static final long serialVersionUID = -8039686696076337053L;

  @Id
  @GeneratedValue
  @Column(name="ID", nullable = false)
  private Long id;
  @Column(name="USERNAME", nullable = false,  unique = true)
  private String username;
  @Column(name="PASSWORD", nullable = false)
  private String password;
  @Column(name="FIRSTNAME", nullable = false)
  private String firstname;
  @Column(name="LASTNAME", nullable = false)
  private String lastname;
  @Column(name="EMAIL", nullable = false, unique = true)
  private String email;
  @Column(name="CONFIRMED", nullable = false)
  private boolean confirmed =false;
  @Column(name="PHONE", nullable = false, unique = true)
  private String phone;
  @Enumerated(EnumType.STRING)
  private Role role;

My Dao in order to get and set data on User table:

@Repository
public class UserDao{
   public UserDao(){}
}

My service layer that will call the dao UserDaoService:

@Service
@Transactional
public class UserDaoService {

  @Autowired
  private UserDao userDao;

  public UserDaoService(){
     super();
  }

  public void create(final UserEntity entity) {
     userDao.create(entity);
  }

  public UserEntity findOne(final long id) {
     return userDao.findOne(id);
  }

  public List< UserEntity > findAll() {
     return userDao.findAll();
  }
}

My rest implementation of UserController:

 @Controller
@RequestMapping(value = "/user")
public class UserController {

  @Autowired
  private UserDaoService userDaoService;

  @RequestMapping(value = "/getAllUsers", method = RequestMethod.GET)
  @ResponseBody
  public List< UserEntity >findAll(){
     return userDaoService.findAll();
  }

  @RequestMapping(value = "/getUser/{id}", method = RequestMethod.GET)
  @ResponseBody
  public UserEntity findById(@PathVariable("id") Long id){
     return userDaoService.findOne(id);
  }
}

When I tried to retrieve my users from the database instead of seeing my users as a json response:

 
[
 {
   id: 1,
   username: "test",
   password: "test",
   firstname: "vag",
   lastname: "pap",
   email: "test@gmail.com",
   confirmed: false,
   phone: "1234567",
   role: null
 },
 {
   id: 6,
   username: "test2",
   password: "test",
   firstname: "test",
   lastname: "test",
   email: "test@yahoo.gr",
   confirmed: false,
   phone: "1234567",
   role: null
 }
]

I got  LazyInitializationException. But what is it really the LazyInitializationException? The best answer I found on the web is the the following:

"This error means that you’re trying to access a lazily-loaded property or collection, but the hibernate session is closed or not available . Lazy loading in Hibernate means that the object will not be populated (via a database query) until the property/collection is accessed in code. Hibernate accomplishes this by creating a dynamic proxy object that will hit the database only when you first use the object. In order for this to work, your object must be attached to an open Hibernate session throughout it’s lifecycle." 

How do we overcome such a problem?

All we need is to mantain the session of our sessionFactory, while the request is processed. In order to succeed this, we need to add an OpenEntityManagerInViewFilter (as we are using hibernate with jpa. For pure hibernate solution you can useOpenSessionInViewFilter ) filter in our web.xml that will bind the session to the thread of the entire processing of the request.

In the provided sample, I show you the use of the specific filter. Check lines 20-27


  
    
     org.springframework.web.context.ContextLoaderListener      
    
  
  
     contextConfigLocation
     classpath*:applicationContext.xml
  
  
     dispatcher
     org.springframework.web.servlet.DispatcherServlet
  
  
     dispatcher
     /
  
  
     OpenEntityManagerInViewFilter
     org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
  
  
     OpenEntityManagerInViewFilter
     /*
  

By doing this, the filter will mantain the session opened (during the request handling) and allow the Lazy fetching.

Vertical Tabs