2009-05-14 6 views
2

DTOパターンを使用して、ドメインオブジェクトをサービスレイヤからリポジトリにマーシャリングし、次にNHibernate経由でデータベースにマーシャリングします。NHibernate、DTOs、NonUniqueObjectException

私は、DTOをリポジトリ(CustomerDTOなど)から取り出し、サービスレイヤのドメインオブジェクト(Customer)に変換するという問題に遭遇しました。次に、同じCustomerオブジェクトを含む新しいオブジェクト(SalesOrderなど)を保存してみます。これは、リポジトリにプッシュするためのSalesOrderDTO(およびCustomerDTO)に変換されます。

NHibernateはこれを好まない - それは、CustomerDTOが重複したレコードであると不平を言う。私はこれが同じセッションで最初のCustomerDTOを引っ張ったためであると仮定しています。戻り値が前後に変換されているため、これを同じオブジェクトとして認識できません。

私はここにこだわっているのですか、これを回避する方法はありますか?

おかげ

ジェームズ

あなたはロックを使用してNHibernateの中のセッションにオブジェクトを再接続することができ

答えて

2

- 例えば

_session.Lock(myDetachedObject, NHibernate.LockMode.None); 

ここで何が起こっているのかによって正確には助けないかもしれません。副作用として、NHibernateでDTOを使用するのが最も一般的な方法ではありません.Hibernate(主に)が永続性の無知をサポートしているという事実は、通常DTOは他のORMフレームワークと同様に広く使われていないということです。

+0

返信いただきありがとうございます。私のドメインオブジェクトはプロパティでパブリックメソッドを設定していないため、私はDTOを使用しています。私はその後、工場を使ってDTOからドメインオブジェクトを作成します。 私の問題は、どのオブジェクトを再接続する必要があり、どのオブジェクトを新しいものにするかを知ることになると思います。たぶん、私のアプローチを考え直す必要があるかもしれません:( – James

+2

一部のデータがある場所に格納され、別の場所に格納されているドメインオブジェクト(たとえば、それぞれDBファイルとXMLファイル)がある場合、DTOはしばしば必要です。データマッパーやリポジトリのサンプル実装がほとんど認めない複雑さの複雑さ。私はギャップを埋めるためにMartin FowlerのPoEAAを読むことを勧めます:http://is.gd/NmTt –

2

これはNHibernateセッションの仕組みに関するものです。したがって、セッション内でCustomerDTOのインスタンスを取得してからしばらくしてから、同じCustomerDTO(プライマリキーなど)を取得する必要があります。最初の取得時と同じように、同じオブジェクトへの参照が実際に取得されます。

それでは、session.Mergeを呼び出してオブジェクトをマージするか、session.Get(primaryKey)を呼び出してセッションを要求し、セッションをフラッシュします。

スティーブにより示唆されるようにしかし - これはないが、通常、あなたは何をすべきか - あなたが本当にデータストアからあなたのドメインオブジェクトを取得し、UIにデータを転送する(neede場合)のDTOを使用する場合は、Webサービスを何でも...

1

私はそれが が で同じセッションを最初CustomerDTOを引き抜いているためと返す はそれが 同じオブジェクトとしてこれを認識できない背中や 前後変換されているためであると仮定しています。

あなたは正しいです。休止状態はできません。これを修正するには、EqualsとHashcodeを実装することを検討してください。私はあなたがこのセッション内でオブジェクトをロードしていない場合にのみ再接続が機能するかもしれないと思います。

2

他にも述べたように、EqualsとGetHashCodeを実装することは正しい方向への一歩です。また、 "attach" OR/Mイディオムに対するNHibernateのサポートを見てください。

はまた、あなたの処分でnosetter.camelcaseオプションがあります:http://davybrion.com/blog/2009/03/entities-required-properties-and-properties-that-shouldnt-be-modified/

さらに、私はあなたがオンラインでそこに情報の欠如によって思いとどまらされていない奨励したいと思います。それはあなたが狂っていることや、間違っていることを意味しません。それは単にあなたが最悪の場合に取り組んでいることを意味します。残念ながら、NHibernateのような図書館の最大の消費者は、単一のデータベースに対するあなたの永続性の必要性をすべて自由にすることができる自社内および/またはWebアプリケーションです。実際には、この規則には多くの例外があります。

たとえば、私のドメインオブジェクトの1つが、SQL CEデータベースとディスク上のイメージファイルの間にデータを分散させた市販のデスクトップアプリケーションに取り組んでいます。残念ながら、NHibernateはSQL CEの永続性を助けるだけです。私は一種の "Double Mapping"(Martin Fowler's "Patterns of Enterprise Application Architecture"を参照)を使って、どのデータがNHibernateに移動し、何がディスクになるのかを知っているリポジトリ層を通して私のドメインモデルをマップしなければなりません。

それが起こります。本当の必要です。時にはツールに明らかな欠点があると、あなたが悪いアプローチをしていることを示していることがあります。しかし時には真実はあなたが本当に最悪のケースにあるということです。そして、あなた自身がそれを達成するためにこれらのパターンのいくつかを構築する必要があります。