4

I'm using Spring data which is easy to use but i can't control it because i got error there

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: entity.Qualite.fonctions, could not initialize proxy - no Session

I know FetchType.EAGER will work but i want keep it lazy. so how can i control the session in spring data

@RequestMapping(value="/loadfonction") 
public @ResponseBody
Set<Fonction> loadfonction(Map<String, Object> model, HttpServletRequest request) { 

    Set<Fonction> fonctions = qualiteRepo.findOne(Integer.valueOf(request.getParameter("idquality"))).getFonctions();

    System.out.println(fonctions.size());

    return fonctions;


}

I even try @Transactional annotation but it didn't work:

@Transactional
@RequestMapping(value="/loadfonction") 

3 Answers 3

2

This is a common problem with trying to open a view using the spring mvc framework. The control method closes the session before the view can display it. (Trying to keep the view out of the business logic) To get around it you can use the OpenSessionInViewFilter class.

Here is an article on how to implement it:

http://blog.cloudmate.pl/2010/09/hibernates-open-session-in-view-in.html

2
  • the problem is not in the view level.
    – Hayi
    Commented Jan 22, 2014 at 23:37
  • Jimmy is right, the problem is around your transactional boundaries. @Transactional should be at your service layer (business methods should be transactional, not finer-grained DAO/Repository methods) and you should ideally not be exposing JPA entities beyond your service layer (beyond the transactional/session boundaries). OpenSessionInViewFilter is a workaround to an imperfect design.
    – Matt Byrne
    Commented Jan 29, 2014 at 10:56
2

In your repository you cannot use query methods to initialize the collection. Instead you should define a query like that to fetch the collection with it. Change your query according to your domain, I can't really figure out how it should look for you.

@Query("SELECT q FROM Qualite q JOIN FETCH q.role WHERE q.fonctionId = (:fonctionId)")
public Qualite findById(@Param("fonctionId") String fonctionId);
1

You can't. The only way to avoid this problem is to do a query when you want to retrieve the Fonction objects.

2
  • it's impossible with spring data or also if i migrate to hibernate where i can control session and transaction ?
    – Hayi
    Commented Jan 22, 2014 at 23:38
  • I'm not sure about it but, I think if you are in a transaction you can call to some method to reload the lazy collection. I read something of that many time ago but I never used it.
    – JCalcines
    Commented Jan 23, 2014 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.