Hibernate查询缓存中的代理对象与实体类中的Equals方法共造的大坑

本文探讨了在使用Hibernate框架时,如何正确处理实体对象与代理对象之间的equals方法比较问题,尤其是在启用了缓存的情况下。

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

由于项目使用的是Hibernate技术,并设置了二级缓存与查询缓存,各实体的关联对象都是以懒加载的方式,所以,在使用HQL查询后,关联对象在缓存中保存的是一个代理对象,并不是真正的实体对象,如下HQL执行后,t.user的user在缓存中是一个代理对象:
<!-- lang: sql -->
select t, t.user from Book t where t.id = 1024

而User实体类在NetBeans自动生成的equals方法中,有这么一段:
<!-- lang: java -->
if(getClass() != obj.getClass()){
        return false;
}

所以即使另一个实体类user2与查询出来的user1(t.user)有同样的id,account,name,但user2.equals(user1)总是return false; 因为user2.getClass() = User, 而user1.getClass() = User$javassist_28,所以要想正确比较两个User对象,有两点可以解决:
  1. 将实体类User定义为final,那么Hibernate将不能为user结果生成代理对象,只能是User类,但Hibernate不推荐此举。
  2. 改变比较方式,直接使用 if (!(obj instanceof User))比较,代理对象user1是User子类的对象。

转载于:https://my.oschina.net/u/209967/blog/141383

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值