使用 hibernate 快一年了,一直使用得比较肤浅,甚至没有正式使用过对象关系。近段时间想深入研究一下,以便在项目中推广,减少不必要的对象维护和编程。问题不期而遇,在多对多关系中,出现了递规加载的现象,例如:用户和角色的关系,一个用户可能有多个角色,一个角色中包含多个用户。我是通过带有连接表的多对多关系实现的,用户和角色对象中都维持了一个 Set 对象,用以延迟加载关系。但是,在我延迟加载用户拥有的角色时,被加载的角色又加载它所包含的用户,被加载的用户又加载所拥有的角色,这样递规加载下去,由于 session 的关闭会抛出异常导致程序中止。开始百思不得其解,在仔细查看抛出的异常堆栈时,终于发现了问题所在。习惯!错误的习惯。我们所使用的持续层对象会继承一个基础类,该类“实现”了 hashCode equals 方法,代码如下:

public boolean equals(Object o) {

    return EqualsBuilder.reflectionEquals(this, o);

}

public int hashCode() {

return HashCodeBuilder.reflectionHashCode(this);

}

hibernate 将用户所拥有的角色对象放进 Set 中,实际 Set 会调用 hashCode equals 来判断两个对象是否相等,这样问题就来了, HashCodeBuilder.reflectionHashCode(this) 方法使用反射调用角色对象的 getUsers() 方法, hibernate 又加载角色所包含的用户,能没有问题吗?继而我们得反思一下持续层对象有没有通用的 hashCode equals 方法。

       参考《深入浅出 Hibernate 》对 hashCode equals 方法的处理有两大种:

1、  不覆盖

问题:实体对象的跨 session 识别问题,根本在于 hashCode 默认调用 System.identityHashCode() 方法。

2、  覆盖

Ø         使用对象 pk

问题:新增对象时,没有 pk ,那么所有的对象都相等了,也就是只能加入的一条。

Ø         值比对(对实体对象的所有属性值进行比对,可以使用 Commonclipse 自动生成)

问题:过于严格。

Ø         业务关键信息判定

是值比对的一个子集,只做业务关键属性的比对。

个人觉得业务关键信息判定的方法比较合理,使用 Commonclipse 自动生成值比对,注意两点:

1、  去掉实体关联集合属性的比对,不然又会出现我上述的“递规加载”现象。

2、  自动生成的 hashCode 方法去掉 appendSuper(super.hashCode()) ,自动生成的 equals 方法去掉 appendSuper(super.equals(object)) ,不然你的对象比较和加入 collection 都有问题的,《深入浅出 Hibernate 》书中没有强调。

posted on 2007-01-13 19:13 野草 阅读(781) 评论(1)  编辑  收藏 所属分类: 2shtv

评论:
# re: 持续层对象的hashCode和equals方法 2008-01-13 22:40 | java综合网
java综合网
http://www.javazh.cn
很好!不错!  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: