该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2003-10-16
我其实不喜欢举严肃的例子,但是muziq一定要逼我出手
如果一个erp系统,对一个部门department ,有一个employee 数组,很大,有一个收入revenue数组,更大。 一个国家,有地理资源数组,有商业资源数组,有政治文化资源数组。 一个部队,有历史战绩,有武器编制,有技术合作 ................... 其实数组不数组也不重要,关键在于这个大的资源它并不一定要随着它依附的对象同时初始化。 我给gavin去了mail,他不理我,如同robin所说的。 我觉得不管可以试试,单恐怕不象我们想象的那么简单。有问题再请教大家。多谢了!!! muziq 写道 robbin说的很有道理,但是我看lazy loading只是问题的表面,其实问题的根源是来自于Session。用Session对象管理持久性是Hibernate的核心思想,而在Session的控制以外,你的PO就不是Persistant Object而是Transient Object了,有了这个前提,大概永远不可能“透明”的lazy loading,我猜可能AOP可以做的到(对AOP只有很浅的认识,不敢妄下结论)。
在DAO里面设计带开关参数的方法或者设计多个取不同关联集合的方法看起来是折衷的方法,但是它却是可以满足业务需求的,在特定的业务情景下取不同的关联对象组合,比如员工可以1对多关联工资记录、考勤记录等等,而在工资管理中就只会用到工资记录的关联,在考勤管理中就只会用到考勤记录的关联,而且,从设计的角度看,SessionBean中的业务逻辑与Session也是不打交道的,业务逻辑与数据层有了一定的界限。这时你一定会说这不透明,其实业务逻辑就是为了满足业务的需求,需求里面没有要求你一定要透明啊,只是程序员一厢情愿的想要透明而已。注意,是业务的需求而不是技术的需求,所谓的技术需求就是技术人员的想象,有的时候可以改善实现从而更好的满足业务需求,有的时候却是多余的。技术上实现了“透明”以后,对业务需求究竟有多大帮助,这是个问号。 robbin,flosed:我们不如拿一个真实的、完整的例子讨论一下,这样下去全是在摆空手道,没个完的。Playboy的例子虽然很好玩,但是不够真实(对wife其实应该是1对1吧,除非这是在阿拉伯国家 ),也不够完整。 |
|
返回顶楼 | |
发表时间:2003-10-16
呵呵,挺好的,有争论论坛才热闹嘛。
大家继续讨论。 flosed,你如果有兴趣做这方面的工作,我一定大力支持。不是口头支持,我们可以提供CVS,CVSTrac,Newsgroup,Mailing List,wiki等等服务来支持这个开发工作。而且我对这个问题多少也比较感兴趣,说不定我也会参与。 |
|
返回顶楼 | |
发表时间:2003-10-16
flosed 写道 我其实不喜欢举严肃的例子,但是muziq一定要逼我出手
如果一个erp系统,对一个部门department ,有一个employee 数组,很大,有一个收入revenue数组,更大。 一个国家,有地理资源数组,有商业资源数组,有政治文化资源数组。 一个部队,有历史战绩,有武器编制,有技术合作 ................... 其实数组不数组也不重要,关键在于这个大的资源它并不一定要随着它依附的对象同时初始化。 我给gavin去了mail,他不理我,如同robin所说的。 我觉得不管可以试试,单恐怕不象我们想象的那么简单。有问题再请教大家。多谢了!!! 我只是说例子要真实、完整,并没说一定要严肃啊 你的例子够真实,但不完整,因为只讲了实体关系,没讲实际的操作--系统用户的操作,而不是SessionBean的操作 任何系统都无法脱离用户需求而存在,我想大家都不反对这一点吧 |
|
返回顶楼 | |
发表时间:2003-10-16
如果我要浏览一个公司的简单信息时,是否需要把employee ,revenue,tax等全部load到内存中呢。
假设集团CEO muziq查看旗下公司运营概况时(这时只load company 对象),发现有个hibernate公司怎么上季度现金流为负200万,于是他打算看看公司的具体revenue情况(这时load了 revenue 对象)。发现原来其中一个flosed负责的部门申请了很大一笔资金购买设备。于是他再去查看公司固定资产明细(这时load 固定资产对象),发现买了一批恶贵无比的IBM机器,他怀疑这flosed从中拿了好处,于是叫财务部门核价。财务经理robbin只关心设备价格,就从固定资产明细(这时已经load好了)中拿到价格,到几IBM代理中询问,发现没有什么偏差。于是muziq只好作罢。接着去查其他jdo,jboss公司了。 在这两个操作流程中,所有的资源都只在需要时load。这就是robbin 和我想要实现的load on demand. robbin,我先试试,如果有需要肯定会向你伸手的,谢了先!! muziq 写道 flosed 写道 我其实不喜欢举严肃的例子,但是muziq一定要逼我出手
如果一个erp系统,对一个部门department ,有一个employee 数组,很大,有一个收入revenue数组,更大。 一个国家,有地理资源数组,有商业资源数组,有政治文化资源数组。 一个部队,有历史战绩,有武器编制,有技术合作 ................... 其实数组不数组也不重要,关键在于这个大的资源它并不一定要随着它依附的对象同时初始化。 我给gavin去了mail,他不理我,如同robin所说的。 我觉得不管可以试试,单恐怕不象我们想象的那么简单。有问题再请教大家。多谢了!!! 我只是说例子要真实、完整,并没说一定要严肃啊 你的例子够真实,但不完整,因为只讲了实体关系,没讲实际的操作--系统用户的操作,而不是SessionBean的操作 任何系统都无法脱离用户需求而存在,我想大家都不反对这一点吧 |
|
返回顶楼 | |
发表时间:2003-10-17
flosed 写道 如果我要浏览一个公司的简单信息时,是否需要把employee ,revenue,tax等全部load到内存中呢。
假设集团CEO muziq查看旗下公司运营概况时(这时只load company 对象),发现有个hibernate公司怎么上季度现金流为负200万,于是他打算看看公司的具体revenue情况(这时load了 revenue 对象)。发现原来其中一个flosed负责的部门申请了很大一笔资金购买设备。于是他再去查看公司固定资产明细(这时load 固定资产对象),发现买了一批恶贵无比的IBM机器,他怀疑这flosed从中拿了好处,于是叫财务部门核价。财务经理robbin只关心设备价格,就从固定资产明细(这时已经load好了)中拿到价格,到几IBM代理中询问,发现没有什么偏差。于是muziq只好作罢。接着去查其他jdo,jboss公司了。 在这两个操作流程中,所有的资源都只在需要时load。这就是robbin 和我想要实现的load on demand. robbin,我先试试,如果有需要肯定会向你伸手的,谢了先!! 例子仍然很生动,也够用了,只是好像也没什么新鲜内容啊!我觉得自己该说的都说了,真的已经说不出什么新东西了,再说还是那几句话,如果flosed和robbin还坚持自己的观点的话,我也没有办法了。 |
|
返回顶楼 | |
发表时间:2003-10-17
robbin 写道 可是如果Hibernate能够支持PO属性的lazy loading的话,那么数据库底层对我来说就是更透明的了,我甚至不需要去关心数据库的查询效率问题,Hibernate全部给我屏蔽掉了。我更加随心所欲的考虑业务流程的实现,而不需用去关心底层的效率问题了。我想这才是Hibernate要实现的终极目标,让程序员不需要关心数据库层的管理问题,让他们把精力集中到业务代码的实现上来。 似乎是在追求银弹,,别的不说,就是效率问题,期望hibernate解决所有效率问题就不是很现实。 如果说到开发的简便性,单纯的ejb开发可能更容易。开发总是在这些因素之间寻找平衡,期望某个因素最优的时候,必然会导致其他因素变差。再说下去成讨论哲学了 。 lazy loading技术应该能够实现,但个人觉得与其这样实现lazy loading不如分成1-1更合适。因为还要考虑的代码的可维护性等等其他因素,而不是单纯的技术实现的因素。 |
|
返回顶楼 | |
发表时间:2003-11-03
我来凑几句,跨session存取的话,在此之间发生的数据变化应怎样实时变化??
|
|
返回顶楼 | |
发表时间:2003-11-11
如果在第一个session中load好了一个object Foo,然后关闭了,
下次需要用到这个object中引用的另一个对象collection Bar时,先用另一个session重新load一遍Foo,这时Foo和Bar就会绑定到这个新的session中,然后调用 Hibernate.initialize(Foo.Bar) 就可以了。 我在开关jcs下都做了测试。 (如果要自己在Bar对象的已经关闭的session引用上做手脚,要牵扯很多东东) |
|
返回顶楼 | |
发表时间:2006-04-30
唉,Hibernate 所谓的lazy-loading其实只是lazy但不loading,loading是自己的事
|
|
返回顶楼 | |
发表时间:2007-03-01
今天和一个朋友聊到hibernate的lazy load...
也一直用 Hibernate.initialize 来初始化自己需要的东东 但似乎脑子里觉得应该有“透明”的方法,否则论坛里的人应该也会瓜瓜叫了。 于是上javaeye,看hibernate分版块的内容,从第一页看到这一篇,知道原来大家也是这么做的。没有很好的方法, 有点失望。 但是,也想分享一下我在这方面的一点点经验。大家不要发笑哦。 其实我的系统不复杂,也没有很多个DAO, 只有一个 PersistenceService,用它进行对所有对象的持久化工作。 public interface PersistenceService { public <T> List<T> findAll(Class<T> entityClass); public <T> List<T> findAll(Class<T> entityClass, int pageIndex, int pageSize); public List find(String hql, Object[] values); public List find(String hql, Object[] values, int pageIndex, int pageSize); public <T> T get(Class<T> entityClass, Serializable id); public <T> T get(Class<T> entityClass, Serializable id, String[] properties); public <T> T update(T entity); public void delete(Object entity); public void deleteAll(Collection entities); public int bulkUpdate(String queryString, Object... values); } 其中有一个方法 public <T> T get(Class<T> entityClass, Serializable id, String[] properties); 就是取得哪个对象,并且 initialize 相应的 properties。 正如 robbin 上面说的, 显示屏幕是二维的, 我在系统中确实一个时刻也只显示一个“层面”的内容 我的 get方法是这样实现的 @SuppressWarnings("unchecked") public <T> T get(final Class<T> entityClass, final Serializable id, final String[] properties) { return (T) getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Object o = session.get(entityClass, id); if (o == null) { return null; } Hibernate.initialize(o); if (properties != null) { for (String property : properties) { try { Hibernate.initialize(PropertyUtils.getProperty(o, property)); } catch (Exception e) { throw new RuntimeException(e); } } } return (T) o; } }); } 然后在其他地方,就根据需要初始化相应的属性 |
|
返回顶楼 | |