Nhibernate:只读属性导致紧急加载

Nhibernate:只读属性导致紧急加载,nhibernate,Nhibernate,我们最近升级到了NHibernate 3.3.3.4001的最新版本,我遇到了NHibernate 2.1.2.4000中不存在的问题。这让我相信这可能是新内置字节码提供程序的一个问题 考虑以下映射: <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Foo.Core.Domain" assembly="Foo.Core

我们最近升级到了NHibernate 3.3.3.4001的最新版本,我遇到了NHibernate 2.1.2.4000中不存在的问题。这让我相信这可能是新内置字节码提供程序的一个问题

考虑以下映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Foo.Core.Domain" assembly="Foo.Core" default-access="property">
  <class name="EntityA" table="EntityA" lazy="true">

    <id name="Id" column="EntityAId">
      <generator class="native" />
    </id>

    <many-to-one name="EntityB" column="EntityBId" class="EntityB" not-null="true" />
    <many-to-one name="EntityC" column="EntityCId" class="EntityC" not-null="true" access="readonly" insert="true" update="false" />


  </class>
</hibernate-mapping>


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Foo.Core.Domain" assembly="Foo.Core" default-access="property">
  <class name="EntityB" table="EntityB" lazy="true">

    <id name="Id" column="EntityBId">
      <generator class="native" />
    </id>

    <many-to-one name="EntityC" column="EntityCId" class="EntityC" not-null="true"  />

  </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Foo.Core.Domain" assembly="Foo.Core" default-access="property">
  <class name="EntityC" table="EntityC" lazy="true">

    <id name="Id" column="EntityCId">
      <generator class="native" />
    </id>


  </class>
</hibernate-mapping>
当我调用EntityA实例的Session.Get时存在此问题-它会立即导致为其相应的EntityB发出select:

Session.Get(Of EntityA)(id) ' Causes the EntityB that EntityA references to be loaded as well.
我最好的猜测是,字节码提供程序在构建代理时导致对我的readonly EntityC属性求值,这将强制加载引用的EntityB


有没有办法避免在NHibernate 3.3.3中使用这种类型的模型时出现急迫负载?

我在NH 3.3.3 SP1上对此类层次结构和映射进行了一些测试,以下是我的观察结果:

使用session.Get加载EntityA,然后对该对象执行某些操作 不接触属性EntityB,EntityC,EntityB将 无法加载。触摸任一属性都将触发对的查询 当然,这是正常的

加载EntityA,更新与属性无关的内容 EntityB和EntityC类似于更改EntityA名称,然后回滚 事务处理,不发出其他选择

加载EntityA,不执行任何操作,然后提交事务,第二次选择 对于实体B已发布

加载EntityA,对会话执行一些查询,然后选择 对于EntityB已发布

所有测试均在FlushMode.Auto下完成

通过这些,我得出结论,NHibernate在这种情况下的行为完全是意料之中的:当进行刷新时,NH需要检查对象的脏度,需要获取property EntityC的值以与之前的值进行比较,这就是触发所讨论的选择的原因

这肯定不是因为session.Get或new Proxy。你可以很容易地做更多的测试来证明这一点。不过,我不明白为什么NH2.1.2会有任何不同


我还尝试了NH3.3.1上的测试,响应与NH3.3.3 SP1完全相同。

如果有愚蠢的评论,很抱歉,但是,根据EntityA.EntityC属性代码,我看不出EntityA.EntityC在映射中的意义。EntityC不知道您可以在VB.Net中定义显式只读属性,但是,抱歉,您在CTo中不清楚,在我的实际实现中,这背后有一点——这只是一个人为的例子来说明这个问题——我需要这个专栏用于非规范化报告。我知道你为了简单起见设置了这个清晰的例子。我只是对EntityA.EntityC的这两个语义不同的定义感到困惑,一个在映射中,一个在代码中,我想知道代理类的预期行为。也许你可以解释一下这一点,因为这似乎是你问题的核心。谢谢你的输入-我的测试用例属于负载实体A,什么都不做,然后提交事务。。。你上面提到的案例。现在,你的结论是有意义的-所以让我们考虑一下我上面更新的映射,在这里我有一个EntIa-> Entyc关系映射:INSERT = TrimeUpdate = FALSE——这不会消除FLUH所需的脏检查吗?刚刚测试过。NH Profiler显示第二个SELECT仍然发出。似乎您需要在类和属性中进行不同的排列,或者覆盖NHibernate的脏检查以避免选择。
Session.Get(Of EntityA)(id) ' Causes the EntityB that EntityA references to be loaded as well.