使用Castle.ActiveRecord的注意事项四:using (new SessionScope(FlushAction.Never))

          
      使用 ActiveRecord 作为数据库持久层已经有一段时间,曾经发现这样一个现象,数据库中的一些 Int DateTime 等字段被设置为了 0 0001-01-01 。期间我问技术总工, Hibernate 在查询过程中会不会修改数据库?技术总工回答,绝对不可能!于是我以为是有同事在存入数据的时候没有初始化数据造成的。事实证明,这个我钦佩得五体投地的资深 JAVA 架构师错了。
    答案是会!而且容易引起重大的 BUG
  
     在一对多,多对多的映射使用中,为了防止取到过多的数据,我们会设置 Lazy=True, 延迟加载。在调用延迟加载的对象,都要加上 Using(new SessionScope()). 如下 
    using ( new  SessionScope())
  
{
      AVO a
=AVO.Find(4);
      
int num=a.Blist.Count;
  }
 
问题出来了,在 Using(new SessionScope()) 的数据都是Persistent态。(关于Hibernate对象状态知识此处不赘述)
   处于Persistent态的对象发生改变以后,在Session结束以后,会自动的把对象的修改提交数据库。所以AVO对象在SessionScope()里面,初始化以后,数据库未填写的数据如Int,DateTime等基础数据类型会自动初始化为0,0001-01-01等。当SessionScope()结束后,数据便被提交到数据库里面。(谓之:脏数据检查dirty checking)
      倘若int字段是一个关联对象的id,该字段没有写成关联对象。许多字典数据经常这样写
     
         /// <summary>
        
/// CreatorId
        
/// </summary>

        [Property()]
         
public   int  CreatorId
        
{
            
get return creatorId; }
            
set { creatorId= value; }
        }

  那么Creatoid就被设置成了0,当下次被调用的时候,习惯性的

        User user = User.Find(CreatorId);

就会报Could not find User with id 0的错误。何况在每次查询结束以后都提交修改本身就对性能有极大的影响。

解决:

1、、写VO的时候关联的字段都写成对象VO,而不是只存一个ID。这么做,不会根本的解决存入数据的问题,但可以控制BUG的产生。因为引用数据类型可以为NULL,而基础数据类型不行。

          /// <summary>
        
/// CreatorId
        
/// </summary>

        [Property()]
         
public  User Creator
        
{
            
get return creator; }
            
set { creator= value; }
        }

2、很简单,using (new SessionScope(FlushAction.Never))。设置持久态的数据不会自动提交。但是设置了这个以后,在using起作用范围内,事务的TransactionScope 提交会出现一些问题。要主要不能乱使用SessionScope();

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的一些观点

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值