该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-11-23
id是一个基本类型,怎么可能等于null,代码都好写错了
|
|
返回顶楼 | |
发表时间:2004-11-23
cdliujian 写道 id是一个基本类型,怎么可能等于null,代码都好写错了
偶写的id是Long, 不是基本类型, 怎么不可能等于null, 都好配眼睛了 |
|
返回顶楼 | |
发表时间:2004-11-23
针对一个简单的Users类,由tanghan生成的POJO大概是这样:
package com.adt.po; import java.io.Serializable; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; /** @author Hibernate CodeGenerator */ public class Users implements Serializable { /** identifier field */ private Integer id; /** nullable persistent field */ private String name; /** nullable persistent field */ private String password; /** full constructor */ public Users(String name, String password); { this.name = name; this.password = password; } /** default constructor */ public Users(); { } public Integer getId(); { return this.id; } public void setId(Integer id); { this.id = id; } public String getName(); { return this.name; } public void setName(String name); { this.name = name; } public String getPassword(); { return this.password; } public void setPassword(String password); { this.password = password; } public String toString(); { return new ToStringBuilder(this); .append("id", getId();); .toString();; } public boolean equals(Object other); { if ( !(other instanceof Users); ); return false; Users castOther = (Users); other; return new EqualsBuilder(); .append(this.getId();, castOther.getId();); .isEquals();; } public int hashCode(); { return new HashCodeBuilder(); .append(getId();); .toHashCode();; } } 而我在它生成的基础上,把最后的那三个函数各自append了一个相对稳定的业务字段name。用下来感觉不错啊。为什么大家会对这样一个问题争论不休呢? |
|
返回顶楼 | |
发表时间:2004-11-23
weihello 写道 两个实体对象其中一个id为null,就不管三七二十一认为两个不相等. 这是什么逻辑? 1,真的很好奇,我认为id为null是否不等,是个业务需求,而在我做的项目中还没有碰见过,真的希望你能举几个现实例子. 2,因为id为null也有可能相等的情况如果存在,会占实体对象多大一部分?如果很少,我会基类全部只比较id,特殊实体再写业务属性对比. 3,在一个集合中,放入具有相同id,但不同类型的实体,这个应用场景我只在缓存的时候碰见过,这时候,一方面,我会采用uuid,如果不能采用uuid,我也会增加一个key的生成规则. 如果说防止开发人员误用第2条,而采取的强制措施,我就不发表意见了,记得有此和人争论:他们为了防止开发人员的null错误,在每个方法开始都要进行输入参数的判断,如果为null,给出详细错误.(虽然觉得有道理,但我是反对派)[/i] |
|
返回顶楼 | |
发表时间:2004-11-23
youcai, 对于类型的那个,只用一行代码改动就可以避免很多问题的考虑或者莫名其妙的错误,得到更好的语义,我看出来为什么不完善它(当然我不清楚有没有其他的问题),呵呵
|
|
返回顶楼 | |
发表时间:2004-11-23
业务字段不一定就有就有唯一的,不可变的,就像这个论坛的用户信息一样(当然我只是从表面看),说实话,我个人觉得ID本来是最好的。既然这个ID放在实体对象里面,就不代表它仅仅是数据表的主键,而确实是对象自身的标识符。只是由于ID是延迟赋值的,导致这样的矛盾,存在了这样具有奇怪状态的实体。而用业务字段生成hashcode一样会出现HashSet无法重读的现象(当然不会在这样的语义下),只是ID的改变被hibernate隐藏了,不是显式的,所以有点莫名其妙。另外,既然用业务字段来做hashcode之类给我的感觉ID的属性就有点多余了,只是为了迎合关系数据库,象prevayler应该就不需要。
PS 实在不行我可以强制要求所有的entity在new出来之前都保存一次数据库,用工厂创建,当然有点开销,出问题了回滚事务,不知道行不行 |
|
返回顶楼 | |
发表时间:2004-11-23
shenli 写道 youcai, 对于类型的那个,只用一行代码改动就可以避免很多问题的考虑或者莫名其妙的错误,得到更好的语义,我看出来为什么不完善它(当然我不清楚有没有其他的问题),呵呵
一行代码?你是说用利用反射机制的工具类吗?当实体类可以自己包含自己或者many to many时,那有可能导致内存溢出,(我用的是commons_lang的,不知道是不是bug) 我认为更为复杂的实体类是否相同的判断,不是简单的依赖于equals(),相同的对象在不同的场景下,相等的标准不一样,比如用户类,有的关心loginName是否一样,而有的关心电子邮件或者身份证号是否一样. 我个人认为在绝大多数场景下,id足以,因此equals()和hashCode()没必要复杂.真要复杂的,请先举出场景出来. |
|
返回顶楼 | |
发表时间:2004-11-23
youcai 写道 weihello 写道 两个实体对象其中一个id为null,就不管三七二十一认为两个不相等. 这是什么逻辑? 1,真的很好奇,我认为id为null是否不等,是个业务需求,而在我做的项目中还没有碰见过,真的希望你能举几个现实例子. “我认为id为null是否不等,是个业务需求”,我不是很明白。呵呵,抱歉。 实体对象一建立,并非就是来个session.save就了事了。这个实体本身完全可能参与业务计算中。 不止一个人让我举例子了,呵呵,我想看来两位都是习惯新建,然后赋值,接着保存,最后完事了...... 如果实体本身带有行为(不是get,set),这种情况就更加频繁发生了。参考 早前我的TimeRange实现。时间范围这个对象,她本身有交、并、非等等内在行 为。你一新建不可能就直接持久,而是需要和一堆已有的TimeRange交并 非操作后,才最后确定一个实体。 TimeRange,我说明一下: 时间范围对象(startTime-endTime), 本身提供时间范围的交,并,非服务。 比如,我一个录像监控有个时间段, 在客户定义的时间段内就启动并开始监控。 如果客户需要增加一个时间段,他只需要提供新增的时间段,然后系统通过交并非等等操作,计算出最后最新需要监控的时间段。 当然录像监控完全可以不要这么复杂,这里只是一个简单应用的例子。但这个设计是非常有名的,具体出处我给忘了。 满意否?代码我不写了。 |
|
返回顶楼 | |
发表时间:2004-11-23
youcai 写道 一行代码?你是说用利用反射机制的工具类吗?当实体类可以自己包含自己或者many to many时,那有可能导致内存溢出,(我用的是commons_lang的,不知道是不是bug)
好像这个帖子的原意就是为了解决你这个问题的。 |
|
返回顶楼 | |
发表时间:2004-11-23
weihello 写道 不止一个人让我举例子了,呵呵,我想看来两位都是习惯新建,然后赋值,接着保存,最后完事了...... 如果实体本身带有行为(不是get,set),这种情况就更加频繁发生了。参考 然后赋值, 然后交互, 接着保存, 不就把新的时间区间弄好了么? 你举的这个怎么看也没有说明id为null的object之间的相等比较呀??? 另, TimePoint 和 Duration这种设计的出处在domian driven design这本书的part iii: http://www.domaindrivendesign.org/articles/blog/evans_eric_sweating_the_small_stuff.html 有一个open source项目就是实现它的: http://timeandmoney.sourceforge.net/ 这种东西在Hibernate里而言, 只是一个UserType, 是一个Entity的属性, 而不会是一个完整的Entity...... |
|
返回顶楼 | |