Java Spring异常中的延迟加载
在我的控制器中,我有以下代码在数据库中获取特定的表示,将其添加为模型属性并返回详细视图:
@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";
}
在我看来,我试图显示使用JSTL进行延迟加载的演示文稿的一个属性:
${presentation.student.files.proposal.titel}
然而,在Student中有一个“档案”列表,但它使用了延迟加载:
@OneToMany(mappedBy = "student", fetch = FetchType.LAZY)
private List<Dossier> dossiers;
但我有以下例外:
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
当我将“档案类型”设置为“急切”时,我甚至无法运行我的项目:
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
当我在谷歌上搜索时,我发现了以下解决方案:
@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";
}
但它又给了我一个例外:
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
# 1 楼答案
您的控制器没有数据库上下文,因此他不可能获取所有延迟加载数据。您需要做的是直接在模型对象(可能是presentedao-DAO)中编写一个方法,并从该方法将所有元素添加到列表中,然后再将其放入控制器中
# 2 楼答案
您有很多选择:
presentatieDao.getWithDossiers(id)
,在这里您可以做一些事情使它加载档案(比如档案集合上的.size()李>@Transactional
,这将导致会话保持打开状态并正确获取它(但从长远来看可能会减慢应用程序的速度)李>另一个: