最近、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 のクラス定義は次のとおりです。
Public Class EntityA
Public Overridable Property Id As Integer
Public Overridable Property EntityB As EntityB
Public Overridable ReadOnly Property EntityC As EntityC
Get
Return If(EntityB IsNot Nothing, EntityB.EntityC, Nothing)
End Get
End Property
End Class
EntityA のインスタンスに対して Session.Get を呼び出すと、問題が発生します。対応する EntityB に対してもすぐに選択が発行されます。
Session.Get(Of EntityA)(id) ' Causes the EntityB that EntityA references to be loaded as well.
私の最善の推測は、バイトコードプロバイダーが、プロキシの構築時に読み取り専用の「EntityC」プロパティを評価させていることです。これにより、参照されたEntityBのロードが強制されます。
NHibernate 3.3.3 でこのタイプのモデルを使用して熱心なロードが発生しないようにする方法はありますか?