hibernate懒加载解决方式之一

29 篇文章 0 订阅
29 篇文章 0 订阅

hibernate的懒加载有多种解决方式,这里是我使用的其中一种。

hibernate版本:5.2.9.FINAL

场景:有一个记录用户信息的user表,还有一个部门表department,user表里有一个外键字段department_id 对应department表的id,表示该用户所在的部门。因此hibernate的实体类中,User类有一个成员变量是department。

在DAO类中有一个方法根据用户id获取用户信息和该用户所在的部门信息:

    User user = (User)session.get(Useer.class.getName(),id);
    return user;

由于hibernate的懒加载特性,user.getDepartment()获取到的是一个代理对象。如果通过反射将user转换为json对象时会出错,因为user的department变量时一个代理对象。如果在dao的方法里调用user.getDepartment().getName()等方法,是可以的,但是department仍然是一个代理对象。而且由于我将dao的查询方法纳入了spring事务管理,如果对department单独进行一次查询,如:

    User user = (User)session.get(User.class.getName(),id);
    Department department = (Department) session.get(Department.class.getName(),id);
    return user;
department对象仍然是一个代理对象,并且与user.getDepartment()获取到的Department对象是一个实例。这是因为开启了事务管理的原因,整个方法是一次事务,对同一条department数据的查询,在第一次对User进行查询时实际已经存入了hibernate缓存中,无论进行多少次都是hibernate缓存中的一个代理对象。


现在的问题是要把Deparment对象转换为实际的对象,因此采用这样的方法:

方法一:

    User user = (User)session.get(Useer.class.getName(),id);	
    session.clear();
    Department department = (Department) session.get(Department.class.getName(),id);
    return user;
使用session.clear()方法,清空缓存中的对象,因此对Department对象的查询是再次在数据库执行一次语句。

方法二:

String hql = "select u,u.department from User u where u.id = ?";
Query<Object[]> query = session.createQuery(hql);
query.setParameter(0, id);
Object[] objs = query.uniqueResult();
User user = (User) objs[0];
return user;
通过联表查询,由于查询语句中也查询了department对象,hibernate不会对user中的department对象进行懒加载放置到缓存中,而是直接查询并返回一个Department实例。并和user一起填充到一个数组中,此时并不需要从数组中取出Department对象,因为user中的Department对象和数组中的Department对象是一个实例,直接返回user即可。

    User user = (User)session.get(Useer.class.getName(),id);
    return user;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值