论坛首页 Java企业应用论坛

Hibernate延迟加载方式违背分层原则

浏览 9916 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (18) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-04-11  
21xionghua 写道
个人认为 web应用中在分页查看的前提下,禁用延迟加载是有必要的。openSessionInViewFilter固然可以,但session的生命周期过长。如果遇到响应时间长的页面(10秒上)更是问题。



session生命周期过长固然不好,但是提醒一点,session会自动释放数据库链接的

所以就算session生命周期长点也没有什么大不了嘛,不过是个普通的实例而已
0 请登录后投票
   发表时间:2009-05-27  
taupo 写道
21xionghua 写道
个人认为 web应用中在分页查看的前提下,禁用延迟加载是有必要的。openSessionInViewFilter固然可以,但session的生命周期过长。如果遇到响应时间长的页面(10秒上)更是问题。



session生命周期过长固然不好,但是提醒一点,session会自动释放数据库链接的

所以就算session生命周期长点也没有什么大不了嘛,不过是个普通的实例而已


session是个普通的实例,但一直open的session恐怕不这么节能了。既然生命周期过长不会有影响,那么为什么hibernate要提供open和close呢?

个人感觉hibernate的延迟加载具有侵入性,也就是说,它对你定义的领域模型要求强制的实现绑定,你必须在使用到entity的时候考虑模型之外的东西(即session),所以这也是楼主所述问题的核心。

同时,openSessionInViewFilter虽然在一定程度上解决了这个问题,但似乎它是在绕过问题的实质,这种治标不治本的办法很容易给人造成错觉。

所以,我认为,如果让延迟加载真正能够在不违背设计原则的前提下发挥作用,问题的关键应该是在session的管理,也即session的open和close的时机。

AOP的切面注入可能是一个不错的办法,即将领域模型与持久化隔离(即将entity视为与持久化无关的领域对象),当entity访问延迟数据时,切面管理器会自动管理session的动作。

也可以维护一个自己的entity池,隐藏所有对持久数据的CRUD操作,不过这样的话,你就已经创造出来另一个层了。

创建entity的proxy对象,使之代理所有与持久化有关的操作(隐藏session的管理)。

当然以上所述的前提是,你需要这样的策略来使项目更具灵活性,软件是管理复杂性的工作,如果自认为手头的项目复杂性很低,那我强烈建议去找个没人的地方偷着乐...
0 请登录后投票
   发表时间:2009-06-28  
to_rise 写道
并非本本主义这么简单。J2EE 分层结构的原则是各层做各层的事情,
而很明显,访问数据库不是Web层应当完成的事情。
一个好的设计可以预先避免很多问题。

在简单的Web/Buiness/DAO在一起使用时,借助于Spring的OpenSessionInViewFilter在Web层打开Hibernate Session是可以完成程序的正常运作。但在分布式环境或有中间件环境下,如果Web层无法得到Hibernate Session,这种延迟加载方式是有问题的。退一步说,在前述简单环境下,VO对象中属性在调用时一次加载也要比分次加载效率要高。

在Hibernate3的Cirtier查询中的FetchMode.Early中已部分实现指定加载对象层次,但也只限于Cirtier模式查询。

的确如此,在简单的SSH架构设计项目时懒加载很实用也很方便,但在分布式条件下起码到现在为止难于懒加载,还是需要我们自己清楚需要的数据项后进行VO构造。
0 请登录后投票
   发表时间:2009-06-28  
我认为系统设计的时候应该跟数据库无关。根据系统的需要,来进行数据库建模。之后根据domain进行数据库的映射。

[[[[在小型Web网站程序中没有问题。但在分层严格的程序中,当Web层的页面及Action调用对象属性时是不允许再去访问数据库的,如此对象延迟加载也就失去了意义。 ]]]]

这句话不太明白。分层跟数据库访问应该没有多大关系。听你的意思是想数据一直存在?是类似于有状态的session bean吗?
0 请登录后投票
   发表时间:2009-06-29  
延迟加载只是一种提高性能的手段。你可以不用,全部放弃延迟加载。

延迟加载确实让前端对象有了数据库方法能力。但RoR不正这样干的?

既然Hibernate和LZ的分层架构有冲突,那完全可以启用此工具,或者改造此工具。
0 请登录后投票
   发表时间:2009-06-29  
to_rise 写道
写这篇文章本意是控讨延迟加载是否必要,这是个见仁见智的话题.

架构问题并不是本本主义。如果你开发过大中型程序,应当知道多个WEB服务器和业务服务器分开布署的情形。又或者,你需要考虑系统解耦,当子系统通过Web Service访问得到VO对象后,你还能指望VO的延迟加载吗?


其实这个问题吧. 我觉得两边都有道理.

当然虽然这样看上去我像个和稀泥的......

从楼主的角度来说.他觉得延时加载破坏了分层制度.

因为在该访问数据库的时候你不访问. 而是在使用的时候再进行访问.

这就造成了访问时间不可知. 也就是无法预测是何时何地访问.

于是会造成如果取不到 session 的担心. 分布式的 session 管理的担心.

这都是正常的担心. 于是对于楼主. 我建议你关闭所有的延时加载.

这样就不会出现你说的问题...
------------------------------------------------------
同样 对于 支持延时加载的同学, 也是对的.

其实延时加载就是为了避开数据库的并发访问量过大.

说白了.它是一个技术问题. 而不是一个设计问题.

所以.如果你的系统没有分布式 session 管理.

而且对于延时加载保持认可. 不会对系统造成错误.

那么我建议大家仍然使用延时加载. 毕竟它的好处一眼可见.
------------------------------------------------------
最后总结一下. 任何一种技术. 它出现的原因都是我们碰上了一些问题后

提出的解决方案. 那么就好比做事的两面性. 其实技术也是如此.

何时用这个技术, 如何用这个技术. 这才是做程序人的价值.

而不应该仅仅停留在 这个技术好不好. 这个技术差不差这个思想上.

就好比如果 数据库够 NB, 网络够 NB , 内存无限大的情况下.

你说我们要 cache 做什么. 所以特定技术的出现. 肯定是为了解决

特定的问题的. 希望大家在设计自己的系统时, 根据自己的需要.

来选取最合适的方案. 仅此而已. 需要延时就延时. 不需要延时就不要延时.

这样好吧..
1 请登录后投票
   发表时间:2009-06-30  
以前开始学习EE的时候,崇拜那设计“优雅的”分层结构,觉得很好,但是到了公司才知道,快速才是最重要的,什么分层根本就看不到。甚至公司有些人直接就在页面中嵌入代码,去写hql或者sql语句通过action去访问数据库了,一开始看着特不爽,页面中出现sql语句,让我抓狂。
唉……咱也不是什么牛人,刚到公司,菜鸟一个,也不能说太多!
更一开始进公司,看公司人写的代码,在页面开始的时候打开Session,界面结束的时候关闭Session。于是乎不晓得咋个回事,后来才知道,这不就是为了用延迟加载嘛。Open Session In View都不晓得,晕倒~~
0 请登录后投票
   发表时间:2009-10-02  
干脆去除web层,所有页面信息都在service层完成渲染(输出可以是XML或HTML),然后用字符串文本或stream的方式传给web页面。session的生命周期由service层管理,故再也不会出现懒加载的问题。

当然,所有内容都要渲染成XML文本才输出,项目的速度怕是会比较慢,因为这相当于把所有的对象都序列化再输出它们。
0 请登录后投票
   发表时间:2009-10-12  
to_rise 写道
写这篇文章本意是控讨延迟加载是否必要,这是个见仁见智的话题.

架构问题并不是本本主义。如果你开发过大中型程序,应当知道多个WEB服务器和业务服务器分开布署的情形。又或者,你需要考虑系统解耦,当子系统通过Web Service访问得到VO对象后,你还能指望VO的延迟加载吗?


这个是需求考虑的一部分吧, 通常一开始调研 不就要确定 用户规模之类的么, 如果一个单用户blog也为了 解耦合做那么严谨 基本也属于大炮打蚊子 杀鸡用牛刀。 

就向很多内部用的系统, 可能服务器端数据验证都不用写,就5,6不懂电脑的人用,他们搞不出什么花样。

我曾经就发现  一个投票统计的网站  居然SQL注入都不防备,直接URL上敲语句旧能抛过去,别人投票一样统计的很开心,据说前几名还有奖品呢!!!!


0 请登录后投票
   发表时间:2009-10-29  
这个 可用引入另一个 vo 叫 view Object,把所有的东东查出来 封装到 viewobj里面 ,然后 显示。不要延迟加载 我很讨厌它
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics