由于项目使用的是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对象,有两点可以解决:
- 将实体类User定义为final,那么Hibernate将不能为user结果生成代理对象,只能是User类,但Hibernate不推荐此举。
- 改变比较方式,直接使用 if (!(obj instanceof User))比较,代理对象user1是User子类的对象。