spring整合hibernate时lazy加载失败问题

本文介绍了在Spring4和Hibernate4环境下,整合时遇到的LazyInitializationException问题。问题出现在尝试在事务范围之外访问设置了ManyToOne懒加载的字段。文章深入分析了原因,并提出了两种解决方法:使用OpenSessionInViewFilter和在事务内初始化懒加载字段。这两种方法各有利弊,需要根据实际情况选择适用的方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 环境:
  • spring4
  • hibernate4
  • mysql 5.6
2. 原始问题现象:

假设有两个表student和teacher,teachet是student的ManyToOne外键字段,设置如下属性:

@OneToOne(fetch = FetchType.LAZY, mappedBy = "student")

  当没有在spring配置的transaction中直接如此:student.getTeacher()获取teacher时,会发生spring4 org.hibernate.LazyInitializationException: could not initialize proxy - no Session异常;

3. 原因分析:

spirng整合hibernate时,由于数据库的session完全交由spirng负责,而spring对于session的管理是以transaction为原子操作的,即在一个transaction事务操作完毕后session被spring关闭,所以在transaction的方法以外直接读取lazy加载字段时,session必然已经关闭了,进而抛出以上异常;

4. 解决方法:
  • 使用OpenSessionInViewFilter过滤器,在web.xml中配置如下:
<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter<!--这边是hibernate4,其他版本对应好版本号即可-->
</filter-class>
    <init-param>
        <param-name>sessionFactoryBeanName</param-name>
        <param-value>yourdbrSessionFactory</param-value><!--这个sessionFactory是Spring配置文件中配置的bean-->
</init-param>
</filter>
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  该过滤器可以保证在一次http会话过程中,hibernate的session不会关闭,一直到会话结束;
  该方法的弊端:
  (1). 和http会话过于耦合,容易受http请求影响,例如如果请求数据很大或者时间过程,该hibernate的connection一直不能释放,如果服务器请求频繁的话,JDBC的线程池有可能耗光;
  (2). 只能用于http请求;

  • 在hibernate配置的transaction的相关method中,使用静态方法Hibernte.initialize(Object);加载需要使用的LAZY关联字段,参数Object为关联字段,例如student拥有关联外键teacher,并且teacher的fetchtype配置为lazy,那么在service中获取student的方法中最后可以执行Hibernte.initialize(student.getTeacher())操作,则teacher将被加载;

  • 在entity中配置相关字段为:

    @OneToOne(fetch = FetchType.EAGER, mappedBy = "student")

      该方法将保证每次读取student时都会自动加载teacher字段,但是缺点就是如果teacher字段是集合时会降低读取student的速度;

以上方法各有优越点,在实际开发中需要和具体需求结合考虑,综合使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值