私はウェブアプリを持っています。アプリケーション (コマンド ライン) を使用せずにデータベースに変更を加えると、エンティティにこの変更が表示されません。
データが変更され、更新する必要があることをエンティティに認識させる方法はありますか?
私はウェブアプリを持っています。アプリケーション (コマンド ライン) を使用せずにデータベースに変更を加えると、エンティティにこの変更が表示されません。
データが変更され、更新する必要があることをエンティティに認識させる方法はありますか?
JPA はデータベース オブザーバーではなく、基盤となる JDBC もオブザーバーではありません。一部のエンティティに古いデータまたは存在しないデータが含まれていることをデータベース サーバーから通知される方法はありません。知る唯一の方法は、現在のトランザクションを更新するか、コミットしようとすることです。
問題は、リソース ローカル トランザクション タイプを使用していることです。トランザクションの begin() と commit() を設計する義務があります。これは、技術的にはトランザクション境界と名付けられています。EntityManager の保持時間が長すぎると、苦情のように古いデータが発生したり、メモリ リークやパフォーマンスの低下が発生したりする可能性があります。独自のトランザクション管理ポリシーを策定する必要があります。
一方、GlassFish などのアプリケーション サーバー用に開発することで、頭痛の種を回避できます。JTA トランザクション タイプは、通常はサーバーによって注入されるスレッド セーフな EntityManager 用に作成されます。したがって、すべてのトランザクション配管が節約されます。
私の議論は、294ページからの引用に続くJSR-317 JPA仕様を参照しています。
アクティブな JTA トランザクションのスコープ内でコンテナ管理のエンティティ マネージャが呼び出されると、新しい永続化コンテキストが開始されます。永続化コンテキストが作成され、JTA トランザクションに関連付けられます。関連する JTA トランザクションがコミットまたはロールバックすると、永続化コンテキストが終了し、EntityManager によって管理されていたすべてのエンティティが切り離されます。
GlassFish で JTA トランザクション タイプを設定する手順については、この投稿の私の回答を参照してください。
現在の EntityManager での更新よりも、アプリケーションの外部で行われた DB 更新を優先する必要がある場合 - つまり JTA トランザクション - 操作。次に、refresh() 呼び出しまで現在の未完了のトランザクション操作を破棄し、DB の最新状態に頼る EntityManager.refresh() メソッドを使用します。
refresh()
おそらく最も洗練されたソリューションではありませんが、エンティティ マネージャーを呼び出すことができます。この回答を参照してください: Java JPA - データベースとエンティティの同期
または、ペシミスティック ロックを使用して、エンティティの使用中にデータが予期せず変更されるのを防ぐことができます。