关于级联操作中包含了lazy加载,可以优化加载数据。如果采用EAGER方式加载会耗损很多资源。
不过在设置了lazy以后,操作的时候可能会出现Session close的问题。
我查阅了很多资料,lazy加载的方式有几种。
不过我觉得最简单的方式,是加载viewsession。看到别人讨论中,说这种方式可能会导致session无法关闭?我也不清楚,等以后再去研究,暂且先用着吧
Jpa的配置:
hibernate的配置:
以上的信息全部要配置与 web.xml
在配置web.xml中还要注意顺序问题, 应先配置viewsession 然后spring 然后struts
不然也会出现session close的问题。
第二种是AOP动态加载的方式见:
http://www.javaeye.com/topic/129698
使用动态代理AOP结构,来管理EntityManager,这种方案不依赖于容器,在后台服务、测试中都可以良好使用。
这种方式也推荐使用..
以上的方案不修改的Service/DAO模型,侵入性小,测试方便,但是有一些局限性。更良好的方案可以将OpenEntityManagerHandler进行一些修改,
1. 加入private String FACTORY_NAME=DEFAULT_ENTITYMANGER_FACTORY,修改获取EntityManagerFactory的方法。
2. 在applicationContext-*.xml中配置bean,并ref指向EntityManagerFactory的bean。
3. 修改你的Service/DAO模型,引入OpenEntityManagerHandler。
另外还有一种 采用抓取的方式
Hibernate can explicitly initialize the various paths.
For example, let's say we have a PersonDao - we could have this API:
Here is what an implementation of this DAO may look like:
You would use this in your application like this:
This would initialize the mother association, the children association, and each child's mother association (which, would be Jane in this case).
在lazy调用的时候,加了以上的openseesionview信息仍然报错,这个时候就需要检查配置文件。
1.检查事务配置
2.检查Services 事务配置
如果都设定好了,还报错,这个时候需要修改EntityManager在上下文对应的信息,在@PersistenceContext后面增加(type=PersistenceContextType.EXTENDED),就应该可以解决lazy加载的时候,出现的no session or session was closed的错误。 但是需要注意事务处理的时候,会出现其他的问题。
Persistence Context 持久化上下文
Persistence Context是持久化框架需要维护的一个中间容器,其中会存放受管理对象的副本,例如从数据库获取的实体对象,或者调用持久化框架保存过的对象等
主要作用有:缓存(例如NHibernate的一级缓存概念)、支持Flush操作、辅助实现实体以及属性的Dirty检查等
JPA将persistence context分为2种类型:PersistenceContextType.TRANSACTION和PersistenceContextType.EXTENDED。TRANSACTION类型(默认类型)的persistence context生命周期与transaction scope一致,例如事务开始时为生命周期的开始阶段,事务提交或回滚时生命周期结束。EXTENDED类型的生命周期基本与EntityManager一致,在EntityManager创建时开始,在EntityManager关闭时结束。实现Extended类型的persistence context时需要注意其生命周期可能跨越多个事务以及不在事务范围内的情况,伴随的是这些情况下对persistence context中实例对象生命周期以及相关操作的影响,例如version控制等