该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-11-23
Readonly 写道 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...... 谢谢你贴出出处。 至于如何用UserType实现,我并没有采用,这个实现是我前年年底的时候实现的,直接用的就是实体。最初用lido(jdo)实现,后来用hibernate(好像当时初学吧)。深入没有研究, 期待你的实现参考 |
|
返回顶楼 | |
发表时间:2004-11-23
weihello 写道 “我认为id为null是否不等,是个业务需求”,我不是很明白。呵呵,抱歉。 一个实体对象,在不同的应用场景下,判断相等的标准未必固定不变,这时候就不能简单依赖于equals(). 你举的这个例子,id为null的object之间如何比较的? weihello 写道 好像这个帖子的原意就是为了解决你这个问题的。
就是因为这个问题,我才对这种方式保持警惕.后又觉得只比较id对于处理父子关系会非常方面,所以就彻底抛弃掉了. 真有你说的场景,我会考虑再加上,可还是没有碰上 ![]() |
|
返回顶楼 | |
发表时间:2004-11-23
Readonly 写道 weihello 写道 如果实体本身带有行为(不是get,set),这种情况就更加频繁发生了。参考 然后赋值, 然后交互, 接着保存, 不就把新的时间区间弄好了么? 你举的这个怎么看也没有说明id为null的object之间的相等比较呀??? 这是你后来编辑的,无意间看到。 怎么没有比较呢,几个时间段,完全可以录入的啊! 为什么非得一个个处理呀,这里关心的是starttime和endTime呀。 不知道你有没有在网页上做过输入列表,每行输入其实都是一个TO,然后提交,一次性持久。 这个问题我想我们还是到此为之吧。 其实你担心的要么就是 1、贪图便利 其实最后还是不便利,每种ID策略要一个超类(?),减少一些可操作性,组件则区别对待,脱离Hibernate你这个实现无效(呵呵,请不要强调现在是hibernate,注意我们都是程序员). 2、效率,学robbin一句话,请拿出具体案例,说明大幅度减低效率给我看; 3、还有yucai说的,“就是因为这个问题,我才对这种方式保持警惕”, 如果问题 确实出在这里,我可以一次性全部解决,改动也只有一处。 而其说的“真有你说 的场景,我会考虑再加上,可还是没有碰上”却是真正的地雷。 显然,他这样做是 本末倒置,为了贪图方便牺牲其他的一些可操作性。 |
|
返回顶楼 | |
发表时间:2004-11-23
weihello 写道 至于如何用UserType实现,我并没有采用,这个实现是我前年年底的时候实现的,直接用的就是实体。最初用lido(jdo)实现,后来用hibernate(好像当时初学吧)。深入没有研究, 期待你的实现参考
http://forum.iteye.com/viewtopic.php?t=9035 在那个例子里面你可以看到, 一次提交多个, 再进行持久不是什么问题, 只需要在save以前,让这多个对象交互好就行了. 偶的目的就是: 贪图便利 而且实际项目中, 偶们规定不要用HashSet/HashMap之类的Hash容器来存放对象, one-to-many / many-to-many都是用List来处理的, 所以偶的BaseEntity只override掉equals()方法, hashCode()是不去实现的, 是不是贪图便利得超出你的想象? hoho. |
|
返回顶楼 | |
发表时间:2004-11-23
Readonly 写道 weihello 写道 至于如何用UserType实现,我并没有采用,这个实现是我前年年底的时候实现的,直接用的就是实体。最初用lido(jdo)实现,后来用hibernate(好像当时初学吧)。深入没有研究, 期待你的实现参考
http://forum.iteye.com/viewtopic.php?t=9035 在那个例子里面你可以看到, 一次提交多个, 再进行持久不是什么问题, 只需要在save以前,让这多个对象交互好就行了. 偶的目的就是: 贪图便利 而且实际项目中, 偶们规定不要用HashSet/HashMap之类的Hash容器来存放对象, one-to-many / many-to-many都是用List来处理的, 所以偶的BaseEntity只override掉equals()方法, hashCode()是不去实现的, 是不是贪图便利得超出你的想象? hoho. list? 你在映射文件里是list还是bag? list要多一个index列,单向的bag效率又太低,有时候也不得不用set呀 ![]() |
|
返回顶楼 | |
发表时间:2004-11-23
Readonly 写道 shenli 写道 Readonly,你的后面的这种写法在特定场合不管会不会遇到错误,都已经违反了hashCode基本的原则,当两个对象equals方法成立的时候,必须得到同样的散列码
嗯, 偶做错了, 这样会导致: 先做了hashCode操作以后一个未被持久化的object, 和再从数据库里面获得的object虽然equals, 但是hashCode不一样了, 违反了最基本的原则, ![]() shenli 写道 既然一个对象是可变的,我不知道为什么要保证他的散列码不变呢?这个测试(当然不知道谁规定的)这种可重新读出有意义吗?本来在java环境下就没这个要求,不过是hibernate一种特殊的主键产生策略导致的问题?
嗯, java规范里面好像是没有这样的规定, 但是作为一种特定的可持久化对象 (如hibernate这样对应到数据库里的一个row), 在equals的语义上带来的后果: 2个从不同session里面load的对应到同一row的object, 你认为它们是相等还是不相等呢? shenli 写道 刚刚download了hibernate in acdtion的代码,他是在每个entity用业务字段生成的equals和hashCode。原来我也是在一个父类或者mixin中用主键做的,唯一的不同就是用this.getclass == object.getclass取代你的x instance of xxxx
昨天偶问过看过Hibernate in action的人了, 他说书里面有3种做法: 1. 就是偶说的这种用无意义主键做hashCode/equals 2. 就是weihello用的所有值做hashCode/equals 3. 用一个(或者几个)相对稳定的业务字段做hashCode/equals (比如user, 就用userName). hibernate 推荐的是第3种, 按照这种推荐的做法, 就不会出现以上说的所有问题了, 看起来是最佳的实践了. 我还是会坚持我的做法,因为我知道如何去避免潜在的陷阱,至于所谓的基本的原则嘛,嘿嘿,为了可以偷懒。。。 ![]() |
|
返回顶楼 | |
发表时间:2004-11-23
CafeBabe 写道 list? 你在映射文件里是list还是bag? list要多一个index列,单向的bag效率又太低,有时候也不得不用set呀 ![]() 映射文件里面用bag, 单向的bag为什么效率低呢? |
|
返回顶楼 | |
发表时间:2004-11-23
bag在更新时候的效率低哦。
|
|
返回顶楼 | |
发表时间:2004-11-23
http://forum.hibernate.org/viewtopic.php?t=935732
使用cache的时候出现bug |
|
返回顶楼 | |
发表时间:2004-11-23
Readonly 写道 CafeBabe 写道 list? 你在映射文件里是list还是bag? list要多一个index列,单向的bag效率又太低,有时候也不得不用set呀 ![]() 映射文件里面用bag, 单向的bag为什么效率低呢? 因为bag中的元素是可重复的,对单向bag的update,delete操作总是先delete原先所有的 纪录,然后再insert现有的数据。 不过双向的bag缺是效率最高的,因为你往bag里add一个元素是不需要 初始化这个bag的。 说得有点乱 ![]() |
|
返回顶楼 | |