使用
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
野草 阅读(779)
评论(1) 编辑 收藏 所属分类:
2shtv