nhibernate を使用した古い大きな asp.net アプリケーションがあり、その一部を拡張およびアップグレードしています。使用されていた NHibernate はかなり古い (1.0.2.0) ため、新しい機能のために (2.1.2) にアップグレードすることにしました。HBM ファイルは、MyGeneration を使用してカスタム テンプレートを介して生成されます。1つのことを除いて、すべてが非常にスムーズに進みました。
Blog と Post をオブジェクトにする必要があるとしましょう。ブログには多数の投稿を含めることができるため、Post は多対 1 の関係になります。このアプリケーションの動作方法により、リレーションシップは主キーではなく、Blog.Reference 列を介して行われます。
サンプル マッピングと .cs ファイル:
<?xml version="1.0" encoding="utf-8" ?>
<id name="Id" column="Id" type="Guid">
<generator class="assigned"/>
</id>
<property column="Reference" type="Int32" name="Reference" not-null="true" />
<property column="Name" type="String" name="Name" length="250" />
</class>
<?xml version="1.0" encoding="utf-8" ?>
<id name="Id" column="Id" type="Guid">
<generator class="assigned"/>
</id>
<property column="Reference" type="Int32" name="Reference" not-null="true" />
<property column="Name" type="String" name="Name" length="250" />
<many-to-one name="Blog" column="BlogId" class="SampleNamespace.BlogEntity,SampleNamespace" property-ref="Reference" />
</class>
そしてクラスファイル
class BlogEntity
{
public Guid Id { get; set; }
public int Reference { get; set; }
public string Name { get; set; }
}
class PostEntity
{
public Guid Id { get; set; }
public int Reference { get; set; }
public string Name { get; set; }
public BlogEntity Blog { get; set; }
}
ここで、ID が 1D270C7B-090D-47E2-8CC5-A3D145838D9C で参照 1 のブログがあるとします。
古いnhibernateでは、そのようなことが可能でした:
//this Blog already exists in database
BlogEntity blog = new BlogEntity();
blog.Id = Guid.Empty;
blog.Reference = 1; //Reference is unique, so we can distinguish Blog by this field
blog.Name = "My blog";
//this is new Post, that we are trying to insert
PostEntity post = new PostEntity();
post.Id = Guid.NewGuid();
post.Name = "New post";
post.Reference = 1234;
post.Blog = blog;
session.Save(post);
しかし、新しいバージョンでは、Post.BlogId に NULL を挿入できないという例外が発生します。私が理解しているように、古いバージョンでは、nhibernate の場合、Blog.Reference フィールドがあれば十分であり、そのフィールドでエンティティを取得して PostEntity にアタッチすることができ、PostEntity を保存すると、すべてが正しく機能しました。そして、私が理解しているように、新しい NHibernate は Blog.Id によってのみ取得しようとします。
これを解決するには?オブジェクトは制御できないため、DB の設計を変更したり、BlogEntity に ID を割り当てたりすることはできません (これらのオブジェクトは、外部ソースからこのような一般的な「オブジェクト」として事前に入力されています)。