2012-01-18 4 views
0

spring-jpa(休止状態)駆動型WebアプリケーションでエンティティのGetOrCreate(私はensureExistsと呼んでいます)を実装する必要があります。
は私がレイヤードアプリケーション(WS /サービス/ DAL /データストアを)持っていると私はサービス層(春駆動)でこの機能を実装したいです。
基本的な考え方は次のとおりです。JPAセッションと同時にGetOrCreateを実装する方法は?

  1. 検索エンティティ
  2. それを返した場合。
  3. それ以外の場合は、エンティティを保持します。
  4. すべてOKなら返信します。
  5. 一意の制約違反が発生した場合は、エンティティを再度参照して戻すようにしてください。

問題はステップ5は無効になり、例外がスローされると、Hibernateセッションを閉じて再度開くべきであるという事実(セッションのdocumentationから)から生じるが、私はまだ(サービス層では、このロジックをカプセル化したいですそれがDALまたはWSに存在しない)。

私はこれを解決することができる方法についての提案を聞いてみたい、私はアイデアを持っているが、私はそれに向かって答えを傾けないようにと、それを投稿する前に、いくつかの入力を聞きたいと思います。事前に

おかげ

更新
次のように私が考えている解決策は以下のとおりです。
リファクタリングステージ3をダオを受け入れパッケージ(ジェネリック医薬品との)単一ensureExistsメソッドを持っているスコープサービスへそのタイプと実体の間に存在し、伝播はREQUIRES_NEWです。このメソッドは永続化しようとしますが、失敗した場合はもちろん元のサービスで捕捉される例外をスローし、その例外がスローされた場合にも持続しようとします。
これを他の方法でどのように実装できるかについてのご意見をお待ちしております。誰もが、数日で特にお勧めしません場合は
私はコードサンプルと答えとしてこれを投稿し、それを受け入れるだろう。

+0

あなたが計画するように私は私がREQUIRES_NEWとサービスに4〜ステップ1を置く除き、だろう。 –

+0

@JB Nizetなぜあなたはステップ1,2,4をトランザクションにする必要があると思いますか?さらに、論理的にはステップ3だけが異なる抽象レベルにあるので、別のサービスに座ることには何らかの理由があると私には思われます。他のすべてのステップは同じ抽象レベルです(私は思っています)。 – Ittai

+0

私は、 "getOrCreate"メソッドを持っていることを明確にしています。これは例外をスローする可能性があり、必要に応じて外部からリトライすることができます。また、特定のユースケースから再試行ロジック(プロキシまたはインターセプタに抽出された完全に汎用化可能)を切り離します。また、それを返すだけでなく、作成したエンティティで他の何かを行うこともできます。あなたのシステムでは、あなたが取得したエンティティが見つけられ、作成されていればそれが切り離されます。 –

答えて

0

あなたがすべての重要なプロパティを移入し、サンプルオブジェクトで検索する基準のAPI +リフレクションを使用する場合がありますエンティティを検索します。 concurencyの問題を解決するには、悲観的なロックを検討してください。 ロードすると、そのオブジェクトにロックをかけ、すべてのトランザクションが完了したらこのロックを解放します。 パフォーマンスに関して最善の選択肢があるかどうかはわかりませんが、ここでは例外は発生しません。

+0

私は間違っているかもしれないが、私は、あなたが「発見」するとき場合には悲観的ロックを使用することができなくなると思うのステップは、(インデックス列上の単一の列のものを除く)の条件が必要です。 –

+0

お返事ありがとうございました。私は実際にはパフォーマンス犠牲者になるので、悲観的なロックを使用したくない。私はこれが楽観的なロックのための古典的なユースケースだと思うが、私はその目的のために準備する必要がある – Ittai

関連する問題