基于注解的Spring MVC与JPA怎么解决实体的延时加载有关问题

基于注解的Spring MVC与JPA如何解决实体的延时加载问题

本文出处:http://blog.csdn.net/chaijunkun/article/details/7673931,转载请注明。由于本人不定期会整理相关博文,会对相应内容作出完善。因此强烈建议在原始出处查看此文。

Sping和Hibernate在去年年底都发布了新的版本,现在我做的项目都将最新版本的Spring和Hibernate引入了,使用效果良好。不过最近遇到了一个以前没有遇到的问题——实体的延时加载。

对于关系型数据库,表与表之间的某些字段是通过一对多、多对一或者是多对多的关系来维护的,因此Hibernate引入了延迟加载的优化方法。例如一个雇员,包含姓名,性别等等信息,而最重要的就是所属部门。这些员工与部门就存在着多对一的关系。当我从数据库中获取到雇员的时候,假如没有延迟加载优化,那么雇员的信息以及部门相关的属性都会一并加载下来,假如一个部门信息内再有关联的其它信息,那就会占用很多时间来查询。然而有时候,我们获取雇员仅仅是为了显示一下姓名。

上面是针对延迟加载应用场景的一个表述,下面是我的代码:

首先是部门表的关联代码


接下来是雇员的关联代码


这里,雇员表的部门列我使用了延迟加载配置。其它配置都是JPA中普通的注解配置。列名称与属性名称相同时就不用配置@Column注解的name属性。

然后就按部就班地写了表操作的服务及实现。这里就不多说了。

接下来在Spring MVC中标注了@Controller的类的方法中尝试按照雇员id来获取雇员信息:


当我尝试访问http://localhost/show.do?empId=1的时候发现出现了如下的错误:


很明显是由于jpa的entityManager将事务关闭了,因此延迟加载时找不到存在的会话来运行接下来的自动查询。

在网上找了很多资料,最终找到了解决办法:

首先在配置JPA的EntityManager配置文件中加入如下配置:


然后在配置Servlet的配置文件中更改支持@RequestMapping注解的配置:

原来的多数配置都是这样的:


现在我们为这个默认的注解处理映射加入视图内拦截器来自动生成会话:


好了,加入了以上配置后,再访问同样的接口,发现问题解决了。如果你在使用JPA的时候打开了show_sql选项,你会看到执行了两条JPQL语句。