|
该帖已经被评为精华帖
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2004-11-18
多对多双向关系,如果hashCode和equals正常写之,将出现load不上的问题。
详情请看 http://www.erproad.org/showlog.asp?cat_id=30&log_id=371 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2004-11-18
用得着这么复杂吗?比较一下id不就得了。
[code:1] public abstract class EntityBase{ private Long id; public Long getId(){ return id; } //setter... public boolean equals(Object o){ if(this==o) return true; if(o==null) return false; if(this.id==null) return false; if(getClass!=o.getClass()) return false; EntityBase e=(EntityBase)o; if(e.id==null) return false; return id.equals(e.id); } public int hashCode(){ return id==null?super.hashCode():id.hashCode(); } } [/code:1] |
|
| 返回顶楼 | |
|
最后更新时间:2004-11-19
比较一下ID就行了吗?
呵呵,我是不会这样写的。 至于原因,你都想当然了,我也不说了。 |
|
| 返回顶楼 | |
|
最后更新时间:2004-11-19
id是不可靠的
如果一个transient po ,id==null but business value equals existed po, .......... |
|
| 返回顶楼 | |
|
最后更新时间:2004-11-19
winhello,please copy the formatted java source to here .thanks
|
|
| 返回顶楼 | |
|
最后更新时间:2004-11-19
zingers 写道 id是不可靠的
如果一个transient po ,id==null but business value equals existed po, .......... 一个transient object和一个persistent object, 哪怕它们的business value都相同, 偶还是认为它们是不同的 比较ID有什么说不过去的地方呢?偶N个实际项目中就是这样用的...... |
|
| 返回顶楼 | |
|
最后更新时间:2004-11-19
比较ID不是太好的方法(当然也是可以)。因为新建PO的时候ID一般都为空或者0.
一般都是用业务字段来比较(复合的业务字段等),例如:像XXXname,或者其它的呀。 不过觉得equals与hashCode并没有很大什么,因为平时我们只是用Set,List,Map等,其实很少有记录重复的。有时我们必须允许重复。 现说PO就是一种数据对象(大部时候只有set/get方法),标识它唯一的是它的ID(或者复合ID)(大部分情况下)。 所以我觉得equals与hashCode并没有多大重要性,甚至可以不override。 |
|
| 返回顶楼 | |
|
最后更新时间:2004-11-19
[code:1]
/* * 作成日: 2004-11-19 * * この生成されたコメントの挿入されるテンプレートを変更するため * ウィンドウ > 設定 > Java > コード生成 > コードとコメント */ import java.io.Serializable; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Collection; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; /** * @author Administrator * * この生成されたコメントの挿入されるテンプレートを変更するため * ウィンドウ > 設定 > Java > コード生成 > コードとコメント */ public class BasePersistentObject implements Serializable { public String toString() { return ToStringBuilder.reflectionToString( this, ToStringStyle.MULTI_LINE_STYLE); } public boolean equals(Object o) { if (this == o) { return true; } if (o == null) { return false; } Class lhsClass = getClass(); Class rhsClass = o.getClass(); Class testClass; if (lhsClass.isInstance(o)) { testClass = lhsClass; if (!rhsClass.isInstance(this)) { testClass = rhsClass; } } else if (rhsClass.isInstance(this)) { testClass = rhsClass; if (!lhsClass.isInstance(o)) { testClass = lhsClass; } } else { return false; } EqualsBuilder equalsBuilder = new EqualsBuilder(); try { equalsReflectionAppend(o, testClass, equalsBuilder); while (testClass.getSuperclass() != null && !testClass.getSuperclass().equals(Object.class)) { testClass = testClass.getSuperclass(); equalsReflectionAppend(o, testClass, equalsBuilder); } } catch (IllegalArgumentException e) { return false; } return equalsBuilder.isEquals(); } private void equalsReflectionAppend( Object rhs, Class clazz, EqualsBuilder builder) { Field[] fields = clazz.getDeclaredFields(); AccessibleObject.setAccessible(fields, true); for (int i = 0; i < fields.length && builder.isEquals(); i++) { Field f = fields[i]; if ((f.getName().indexOf('$') == -1) && (!Modifier.isTransient(f.getModifiers())) && (!Modifier.isStatic(f.getModifiers()))) { try { if (Collection.class.isAssignableFrom(f.getType())) { builder.append( f.get(this).getClass(), f.get(rhs).getClass()); } else { builder.append(f.get(this), f.get(rhs)); } } catch (IllegalAccessException e) { //this can't happen. Would get a Security exception instead //throw a runtime exception in case the impossible happens. throw new InternalError("Unexpected IllegalAccessException"); } } } } public int hashCode() { HashCodeBuilder builder = new HashCodeBuilder(17, 37); Class clazz = getClass(); hashCodeReflectionAppend(clazz, builder); while (clazz.getSuperclass() != null && clazz.getSuperclass().equals(Object.class)) { clazz = clazz.getSuperclass(); hashCodeReflectionAppend(clazz, builder); } return builder.toHashCode(); } private void hashCodeReflectionAppend( Class clazz, HashCodeBuilder builder) { Field[] fields = clazz.getDeclaredFields(); AccessibleObject.setAccessible(fields, true); for (int i = 0; i < fields.length; i++) { Field f = fields[i]; if ((f.getName().indexOf('$') == -1) && (!Modifier.isTransient(f.getModifiers())) && (!Modifier.isStatic(f.getModifiers()))) { try { if (Collection.class.isAssignableFrom(f.getType())) { builder.append(f.get(this).getClass()); } else { builder.append(f.get(this)); } } catch (IllegalAccessException e) { //this can't happen. Would get a Security exception instead //throw a runtime exception in case the impossible happens. throw new InternalError("Unexpected IllegalAccessException"); } } } } }[/code:1] |
|
| 返回顶楼 | |
|
最后更新时间:2004-11-19
weihello 写道 比较一下ID就行了吗?
呵呵,我是不会这样写的。 至于原因,你都想当然了,我也不说了。 嘿嘿,你也仔细想想吧 Readonly这回跟我比较一致呀 |
|
| 返回顶楼 | |
|
最后更新时间:2004-11-20
Readonly 写道 zingers 写道 id是不可靠的
如果一个transient po ,id==null but business value equals existed po, .......... 一个transient object和一个persistent object, 哪怕它们的business value都相同, 偶还是认为它们是不同的 比较ID有什么说不过去的地方呢?偶N个实际项目中就是这样用的...... 这个比较ID的超类你不能用于组件类,这是其一. 这个我不多说了. 继承这个类的类语义不完整,留下隐患,一旦涉及到在hashmap这样的结构中,这个实体就有严重的问题. 其二 (修改: 依照你的意思,实体ID相等就是相等............) 你要留意你的业务代码中是否采用了equals之类的代码,如果有,他们都是不可靠的. 炸弹不知道什么时候爆炸. 其三. 懒就是懒,呵呵,我想你该承认. |
|
| 返回顶楼 | |









