|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
时间:2008-07-01
近来做JPA的simple时,不时遇到了几个疑问,我不知为什么JPA的设计者要这样设计一个ORM。
声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间:2008-07-01
[quote] 为什么jpa的merge,要首先去数据库找一下数据,后等到事务提交方生成update的的脚本,我还因此以为自己做的unitTest出错。先去查一下数据库这一步,为什么不能略去呢,虽然在大部分情况下,他应该能在二级缓存中找到这条数据,但,我还是实在看不出理由来[/quote]
merge操作主要目的将非受管对象的状态同步到受管对象中。受管对象构造过程session-》二级缓存-》数据库,发生数据库查找很正常。 [quote]为什么删除一条数据,一定要受控状态下的实体。这就照成了要删除一条记录时,需要再去查询一次,获得一个受控实体后,方能删除。这又是为什么,我怎么一点也没有感觉到它的好处呢。[/quote] 删除[quote]时相关事件的触发,级联删除,缓存更新都依赖于受管对象,所以要先有受管对象。 [quote]你可能最想弄明白受管对象有什么好?[/quote] 有 自动同步,级联,懒加载,缓存,事件这些优点。 |
|
| 返回顶楼 | |
|
时间:2008-07-01
guoshiguan 写道 merge操作主要目的将非受管对象的状态同步到受管对象中。受管对象构造过程session-》二级缓存-》数据库,发生数据库查找很正常。 我知道merge操作主要目的,但为什么要查找了,是设计二级缓存时必要的吗,为什么不直接更新数据库就好,我实在不觉复查找是个正常的事,可能是因为我对二级缓存的实现方式还不了解吧。 guoshiguan 写道 时相关事件的触发,级联删除,缓存更新都依赖于受管对象,所以要先有受管对象。
受管对象的好处要当然知道,但问题是,为什么删除一定要受管对象,级联删除为什么会依赖于受管对象呢。 guoshiguan 写道 你可能最想弄明白受管对象有什么好?
有 自动同步,级联,懒加载,缓存,事件这些优点。 我不是不明白受管对象的好处,我只是不明白,为什么直接做的事,为什么删除操作要变成受管对象以后才能做。 |
|
| 返回顶楼 | |
|
时间:2008-07-01
如果删除前不检查一下,删除一个不存在的对象也正常执行了也很Orz
|
|
| 返回顶楼 | |
|
时间:2008-07-01
引用 我知道merge操作主要目的,但为什么要查找了,是设计二级缓存时必要的吗,为什么不直接更新数据库就好,我实在不觉复查找是个正常的事,可能是因为我对二级缓存的实现方式还不了解吧。
很多人的答案可能都是在更新之前,但是我觉得答案应该是在更新之后。 引用 受管对象的好处要当然知道,但问题是,为什么删除一定要受管对象,级联删除为什么会依赖于受管对象呢。
受控对象存在于JVM内存中,但是数据库已经没有对应的这条数据了,接下来会发生什么? 另外你是如何配置级联的?不要告诉我你没有配置而是自己手动处理 |
|
| 返回顶楼 | |
|
时间:2008-07-01
Joo 写道 很多人的答案可能都是在更新之前,但是我觉得答案应该是在更新之后。 想想我也觉得应该是之后吧,要不更新不成功怎么办。 Joo 写道 受控对象存在于JVM内存中,但是数据库已经没有对应的这条数据了,接下来会发生什么? 另外你是如何配置级联的?不要告诉我你没有配置而是自己手动处理 我的simple还没有做到那一步的说,还没有进行过级联操作过,不过,你这么说倒是有点道理。 不过,实际开发中要删除的实体应该多半是脱管对象吧,也就是说,我要用脱管对象里的ID用JPA的find方法获得一个受控对象,再来对这个对象进行删除,这整个流程怎么都会让人觉得很奇怪吧。 |
|
| 返回顶楼 | |
|
时间:2008-07-01
guoshiguan 写道 我知道merge操作主要目的,但为什么要查找了,是设计二级缓存时必要的吗,为什么不直接更新数据库就好,我实在不觉复查找是个正常的事,可能是因为我对二级缓存的实现方式还不了解吧。 时相关事件的触发,级联删除,缓存更新都依赖于受管对象,所以要先有受管对象。 因为事实jpa的设计就不想即刻做数据库同步,merge后,仍可以更改对象的状态,只在主动flush或auto flush需要时去同步。另外级联merge时,需要知道那些关联对象需要merge,这也需要知道对象的状态,所以需要获取对象的状态(也即是受管对象),虽然受管对象可能跟数据库不一致,但这一点不影响,不一致情况下后面的更新检查抛出异常,或事务提交异常。删除也同理。 另外如hibernate的事务性和readwrite二级缓存设计,在事务成功时,对事务中所发生变化的受管对象进行更新。 举个merge的例子: Student{ @OneToMany List books } 加入一detached的books有books1,books2,而受管对象有books1,books2,book3 那么要如何做数据库同步呢? 第一种方式: update Book set studentId = '' where studentId = 'abc', update Book set student = 'studentId' where id = 'booksId1' update Book set student = 'studentId' where id = 'booksId2' 或是只做一次 update Book set student = null where id = 'booksId3' 二级缓存又如何将book3与student的关系去除呢? 从设计上说,符合以下条件,可只产生update语句: 1.只有单向关系。 2.二级缓存的设计使用更新则清除。 3.id产生策略采用自动方式(因为jpa规定merge时需要检查对象是否存在)。 |
|
| 返回顶楼 | |
|
时间:2008-07-02
引用 我要用脱管对象里的ID用JPA的find方法获得一个受控对象,再来对这个对象进行删除,这整个流程怎么都会让人觉得很奇怪吧。 ORM框架说:你都不告诉俺你要删哪个? 我怎么知道删哪个? |
|
| 返回顶楼 | |
|
时间:2008-07-04
nihongye 写道 有 自动同步,级联,懒加载,缓存,事件这些优点。
因为Hibernate也实现了JPA,我就拿Hibernate说事了。 除了懒加载和部分事件,没看出其他东西有什么用途,基本上都是和性能调优对立的,我认为放弃那些特性也没什么不好的。 还有就是缓存,除了一级缓存还有点用以外,二级缓存基本无用,即使用了,效率还不如自己控制全局的缓存控制来的灵活,全局的控制还能用上更多的其他缓存技术,而不是局限在Hibernate中,局限在Java的JVM中(Memcached,不是缓存页面)。 托管对象,造成巨大的Hiberanate学习成本,28原则,Hibernate中80%的陡峭学习曲线就是由这些20%的东西造成的,然后在性能调优上更是浪费不少时间,这和原本提高整个效率的做法背道而驰的,增加设计成本、增加调试成本、增加维护交接成本。 有这点时间,几行编码早就解决了,比如级联就是典型例子。随着对Hibernate的理解越深刻,越发现由级联、托管对象、二级缓存越是太理想化。 |
|
| 返回顶楼 | |
|
时间:2008-07-04
guoshiguan 写道 guoshiguan 写道 merge操作主要目的将非受管对象的状态同步到受管对象中。受管对象构造过程session-》二级缓存-》数据库,发生数据库查找很正常。 我知道merge操作主要目的,但为什么要查找了,是设计二级缓存时必要的吗,为什么不直接更新数据库就好,我实在不觉复查找是个正常的事,可能是因为我对二级缓存的实现方式还不了解吧。 guoshiguan 写道 时相关事件的触发,级联删除,缓存更新都依赖于受管对象,所以要先有受管对象。
受管对象的好处要当然知道,但问题是,为什么删除一定要受管对象,级联删除为什么会依赖于受管对象呢。 guoshiguan 写道 你可能最想弄明白受管对象有什么好?
有 自动同步,级联,懒加载,缓存,事件这些优点。 我不是不明白受管对象的好处,我只是不明白,为什么直接做的事,为什么删除操作要变成受管对象以后才能做。 很简单,只要存在二级缓存的可能,那更新和删除对象,势必要先对比二级缓存中的数据是否需要同步。 你问得很好,完全可以不用级联、二级缓存、merge这些功能,没有必要。 我认为只有在一个事务的范围中,hibernate才有利用价值(比如一级缓存),而且要充分利用。跨事务的话,除了open session in view,其他的都免了吧。 |
|
| 返回顶楼 | |









