Jelle Elaut
Jelle Elaut

Reputation: 17

Lazy Loading in Java Spring exception

In my controller I have the following code getting a specific presentation in my database, adding it as a model-attribute and returning the detail view:

@RequestMapping(value = "/detail", method = RequestMethod.GET)
public String detail(Model model, Principal principal, @RequestParam("id") int id) {
        Presentation p = presentationDao.get(id);
        model.addAttribute("presentation", p);
        return "detail";
}

In my view I'm trying to display an attribute of the Presentation that has lazy loading using JSTL:

${pressentation.student.dossiers.proposal.titel}

However in Student there is a list of 'Dossiers', but it is using Lazy Loading:

@OneToMany(mappedBy = "student", fetch = FetchType.LAZY)
private List<Dossier> dossiers;

but I get the following exception:

org.apache.jasper.JasperException: javax.el.ELException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: domein.Student.dossiers, no session or session was closed

When I set FetchType of dossiers to Eager I can't even run my project:

Severe:   Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build EntityManagerFactory

When I googled I found the following solution:

@RequestMapping(value = "/detail", method = RequestMethod.GET)
    public String detail(Model model, Principal principal, @RequestParam("id") int id) { 
        Presentatie p = presentatieDao.get(id);
        Hibernate.initialize(p.getStudent().getDefinitiefDossier().getVoorstel().getTitel());
        model.addAttribute("presentatie", p);
        return "detail";
}

but it's giving me the follow exception again:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: domein.Student.dossiers, no session or session was closed

Upvotes: 0

Views: 3713

Answers (2)

gotch4
gotch4

Reputation: 13259

You have many options:

  1. you make the collection EAGER
  2. you create another DAO method and you call it presentatieDao.getWithDossiers(id), where you do something to make it load the dossiers (like .size() on the dossiers collection).
  3. You mark the controller method as @Transactional, this will cause the Session to remain opened and will fetch it properly (but may slow down your app in the long run).

Another one:

  1. Try open session in view interceptor http://springtips.blogspot.co.uk/2007/07/open-session-in-view.html

Upvotes: 0

TheMP
TheMP

Reputation: 8427

Your controller does not have the context with database, so that it is not possible for him to get all the Lazy Loading data. What you need to do is to write a method directly in your Model object (probably presentatieDao DAO) and add all elements to the list from this method, before getting it in the controller.

Upvotes: 1

Related Questions