1

@Version アノテーションを使用して、休止状態でバージョン管理を提供しています。私の質問は、DTO からエンティティへのデータの適切なマッピングに関するものです。私が正しいと思う方法は次のとおりですが、もっと良い方法があるかどうか、またはこれがみんなの方法であるかどうかを知りたいです。

  • 電話が私のサービスに来る
  • 更新するエンティティをロードします (バージョン = 1 の AddressEntity を想定)
  • AddressDTO 値を AE にマップし、サブコレクションがあればそれも含めます
  • すべてがマッピングされた後、エンティティ AE をデタッチします (Lazy サブコレクションもマッピングされた後にのみデタッチされます)
  • 今、バージョンを DTO から AE にマップします (休止状態では管理対象エンティティのバージョンを更新できないため)
  • 今、私はマージを呼び出して、この切り離された AE エンティティを更新します

1) これはセマンティクスと論理的に正しい方法ですか?

2) (少し文脈から外れて) 休止状態が既にコンテキスト内にあり、管理されているオブジェクトをマージするためのオーバーヘッドがありますか。つまり、すべての更新にマージを安全に使用できますか、管理されているか管理されていないか、管理されていない場合はマージ + フラッシュのみ、更新後に管理されている場合はフラッシュのみいくつかのプロパティ?

4

2 に答える 2

0
  • すべてがマッピングされた後、エンティティ AE をデタッチします (Lazy サブコレクションもマッピングされた後にのみデタッチされます)

これを単一のトランザクションで実行していると仮定します。DB から取得した永続オブジェクトは、現在のセッションおよびトランザクション コンテキストに関連付けられています。同じトランザクション内で変更された場合、その状態は DB と自動的に同期されます。このメカニズムは と呼ばれautomatic dirty checkingます。これは、Hibernate がセッション内のオブジェクトに加えられた変更を追跡して保存することを意味します。

Transaction tx = session.beginTransaction();
int addressEntityID = 1234;
AddressEntity addressEntity = (AddressEntity) session.get(AddressEntity.class, new Long(addressEntityID));

// set the values from AddressDTO to AddressEntity
tx.commit();
session.close();

オブジェクトは DB から取得され、変更され、トランザクションのコミット時に変更が DB に伝播されます。更新を実行するためにエンティティをデタッチして再アタッチする必要はありません。

  • 今、バージョンを DTO から AE にマップします (休止状態では管理対象エンティティのバージョンを更新できないため)

管理されたバージョニングは楽観的ロックを実装するために使用され、エンティティのバージョニングは Hibernate によって管理されます。バージョン番号は単なるカウンター値であり、DTO に保持する必要がある有用な情報はありません。バージョンの値を自分で設定する必要はありません。Hibernate は、最初に を保存するときに値を初期化しAddressEntity、オブジェクトが変更されるたびに値をインクリメントまたはリセットします。

現在のアプリケーション トランザクション (T1) によって読み取られた後、別のアプリケーション トランザクション (T2) が永続インスタンスを同じ項目で更新すると、T2 トランザクションはこのエンティティのバージョン値を変更します。T1 が更新を試みると、エンティティの が変更されたstale object state exceptionため、Hibernate は をスローします。versionをキャッチしてexception、古いデータについてユーザーに通知できます。特に、バージョニングは、更新が失われる問題を防ぎます。オプティミスティック ロックを実装する以外のコンテキストで使用できる意味のある情報がないため、バージョンを DTO から AE に、または AE から DTO にマップする必要はありません。

于 2013-09-11T03:25:20.090 に答える