使用Castle.ActiveRecord的注意事项之四:using (new SessionScope(FlushAction.Never))
Posted on 2011-03-31 09:38 codingsilence 阅读(308) 评论(0) 编辑 收藏 举报使用ActiveRecord作为数据库持久层已经有一段时间,曾经发现这样一个现象,数据库中的一些Int,DateTime等字段被设置为了0,0001-01-01。期间我问技术总工,Hibernate在查询过程中会不会修改数据库?技术总工回答,绝对不可能!于是我以为是有同事在存入数据的时候没有初始化数据造成的。事实证明,这个我钦佩得五体投地的资深JAVA架构师错了。
在一对多,多对多的映射使用中,为了防止取到过多的数据,我们会设置Lazy=True,延迟加载。在调用延迟加载的对象,都要加上Using(new SessionScope()).如下
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
就会报Could not find User with id 0的错误。何况在每次查询结束以后都提交修改本身就对性能有极大的影响。
解决:
1、写VO的时候关联的字段都写成对象VO,而不是只存一个ID。这么做,不会根本的解决存入数据的问题,但可以控制BUG的产生。因为引用数据类型可以为NULL,而基础数据类型不行。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
3、为什么我的技术总工大人没有意识到这个问题呢?因为JAVA中,一般使用SPRING+STRUTS+HIBERNATE的开发模式,而SPRING的样板中SessionFactory Bean中设置了<prop key="hibernate.connection.autocommit">false</prop>,长期模板化的开发而没有去深入研究,所以这个问题没有引起注意了。
4、不要滥用Using(new SessionScope())。因为Lazy=true,导致每次取用关联对象的时候都要加Using(new SessionScope()),所以有些同事喜欢把所有代码一框,加上代码,完事。而对于Lazy的设置,目前貌似也比较有争议。是ORM将来发展不得不考虑的一个问题,有兴趣的可以去看下MATIN FLOW的一些观点