私のプロジェクトにはTicket
、プロパティを持つエンティティがありOwnedBy
ます。nHibernateを使用してチケットをデータベースに永続化しています。
潜在的なチケット所有者の正規のソースはActiveDirectoryです。チケットをロードするたびにActiveDirectoryにクエリを実行する必要がないため、チケットをフェッチするときにデータベースに永続化してそこからロードします。Ticket.OwnedBy
チケットの所有者が再割り当てさOwner
れると、Active Directoryから新しいものを取得して割り当て、 Ticket.OwnedBy
Session.SaveOrUpdate(ticket)を呼び出します。トランザクションをコミットすると、同じIDを持つがすでにセッションに関連付けられているNonUniqueObjectException
ため、NHibernateはをスローします。Owner
クラス定義
class Ticket {
public int Id { get; set; }
public Owner OwnedBy { get; set; }
/* other properties, etc */
}
class Owner {
public Guid Guid { get; set; }
public string Name { get; set; }
public string Email { get; set; }
/* other properties, etc */
}
流暢なnHibernateマッピング
class TicketMap : ClassMap<Ticket> {
public TicketMap() {
Id(x => x.Id);
References(x => x.OwnedBy)
.Cascade.SaveUpdate()
.Not.Nullable();
/* other properties, etc */
}
}
class OwnerMap : ClassMap<Owner> {
public OwnerMap() {
Id(x => x.Guid)
.GeneratedBy.Assigned()
Map(x => x.Name);
Map(x => x.Email);
/* other properties, etc */
}
}
サンプルコード
// unitOfWork.Session is an instance of NHibernate.ISession
Ticket ticket = unitOfWork.Session.Get<Ticket>(1);
Owner newOwner = activeDirectoryRepo.FindByGuid(/* guid of new owner, from user */);
ticket.OwnedBy = newOwner;
unitOfWork.Session.SaveOrUpdate(ticket);
unitOfWork.Commit(); // Throws NonUniqueObjectException
nHibernateに既存Owner
のプロパティを接続されていないプロパティのプロパティで上書きしてほしい。(ADからフェッチしたオブジェクトの名前または電子メールは異なる場合があり、ADが正規のソースであると想定されます。)SaveOrUpdate(ticket)の前に呼び出してみましSession.SaveOrUpdateCopy(ticket.OwnedBy)
たSession.Merge(ticket.OwnedBy)
が、例外がスローされます。についてのこの関連する質問も読みましNonUniqueObjectException
たが、Session.Lock()の呼び出しも機能しませんでした。
2つの質問があります:
- nHibernateを私の意志に合わせて曲げる簡単な方法はありますか?
- ADからフェッチした所有者を、DBに格納している所有者と同じタイプとして処理しようとして、アーキテクチャ上の誤りを犯した可能性があります。nHibernateを自分の意志で曲げる必要がないように、このデザインをどのように改善できますか?