NHibernate 透明代理的副作用

本文通过一个具体的案例探讨了NHibernate透明代理的问题。在使用NHibernate进行对象持久化时,透明代理可能导致内部属性访问异常。文章揭示了如何调试并解决此类问题,并提醒开发者在采用NHibernate充血模型时需要注意的事项。
一个bug调试了半天,才发现跟NHibernate透明代理有关。
用测试代码验证了一下:
ClassA有两个属性S1和S2,S1使用NHibernate持久化,S2不需要持久化。

public class ClassA
{
    
private int _id;
    
private string _s1;
    
private string _s2;

    
public virtual int ID
    {
        
get { return this._id; }
        
set { this._id = value; }
    }

    
public virtual string S1
    {
        
get { return this._s1; }
        
set { this._s1 = value; }
    }

    
internal virtual string S2
    {
        
get { return this._s2; }
    }

    
public virtual ClassA DoSomething(string s1, string s2)
    {
        
this._s1 = s1;
        
this._s2 = s2;
        
return this;
    }
}

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="AA.CMS" assembly="aa.cms">
    
<class name="ClassA" table="TableA">
        
<id name="ID" >
            
<column name="ID" sql-type="NUMBER(8,0)" not-null="true"/>
            
<generator class="assigned" />
        
</id>
        
<property name="S1" >
            
<column name="S1" sql-type="NVARCHAR2" length="25" not-null="false"/>
        
</property>
    
</class>
</hibernate-mapping>

public class ClassB
{
    
public string Get(ClassA a)
    {
        
return a.S2;
    }
}

测试代码:
[Test]
public void Test()
{
    ISession session 
= TestSetup.GetSession();
    ClassA a1 
= session.Load<ClassA>(1);
    ClassA a2 
= a1.DoSomething("xxx""yyy");
    ClassB b 
= new ClassB();

    DebugUtil.Output(a1.GetType().FullName);
    DebugUtil.Output(a1.S1 
+ " --- " + b.Get(a1));
    DebugUtil.Output(a2.GetType().FullName);
    DebugUtil.Output(a2.S1 
+ " --- " + b.Get(a2));
    session.Close();
}

输出结果:
CProxyTypeAA_CMSClassACMS_NHibernate_ProxyINHibernateProxy1
xxx ---
AA.CMS.ClassA
xxx --- yyy

session.Load()返回的实体对象都是一个透明代理,当访问这个透明代理的public方法(NHibernate要求这些方法都是virtual类型的,用于从它继承实现透明代理对象)时,构造出实际的实体对象。
问题表现在ClassB.Get()方法里面,它访问的是一个internal类型的属性S2,当传入的是一个透明代理时,internal的属性值S2无法获取到。可能是透明代理在internal类型的方法处理上有问题。

如果想基于NHibernate使用充血模型,得好好注意透明代理的一些副作用了。

转载于:https://www.cnblogs.com/RicCC/archive/2007/08/27/870685.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值