最近、永続化プロバイダーを OpenJPA の使用から EclipseLink の使用に変更したプロジェクトに取り組んでいます。これは大規模で古いアプリケーションであり、当面 JPA に移行することが現時点では不可能な他のプロセスからの SQL 挿入も行います。
@TableGeneratorを使用して、挿入で使用する ID を追跡するテーブルを参照します。
OpenJPA を使用したとき、最初にテーブルから次の ID を選択し、次にテーブルを更新して次の ID を事前に割り当てていることに気付きました。これは、古い SQL プロセスが次の ID を取得して事前に割り当てる方法とまったく同じです。
EclipseLink に切り替えたとき、逆の動作に気付きました。テーブルを更新して次の ID を事前に割り当ててから、挿入を開始します。これにより、java.sql.SQLIntegrityConstraintViolationExceptionが発生します。これは、事前に割り当てられた最後の ID が非 JPA プロセスによって使用されて新しいレコードが挿入されたため、JPA プロセスがその ID に達すると、データベースがエラーを返し、試行中であると主張します。すでに使用されている ID で挿入を行います。
OpenJPAのように事前割り当てを処理するようにEclipseLinkに指示する方法はありますか?
以下は、OpenJPA と EclipseLink の事前割り当て戦略のサンプルです。これらの例では、allocationSizeを 5 に設定しています。
OpenJPA
TEST TRACE [main] openjpa.jdbc.SQL - <t 22760146, conn 3658896> executing prepstmnt 9137209 SELECT NEXT_ID FROM ABC.table_ids WHERE TABLE_ID = ? FOR UPDATE [params=(String) 1034] [reused=0]
TEST TRACE [main] openjpa.jdbc.SQL - <t 22760146, conn 3658896> [94 ms] spent
TEST TRACE [main] openjpa.jdbc.SQL - <t 22760146, conn 3658896> executing prepstmnt 23999306 UPDATE ABC.table_ids SET NEXT_ID = ? WHERE TABLE_ID = ? AND NEXT_ID = ? [params=(long) 55, (String) 10, (long) 50] [reused=0]
TEST TRACE [main] openjpa.jdbc.SQL - <t 22760146, conn 3658896> [93 ms] spent
トップリンク:
[EL Fine]: 2013-01-23 14:08:35.875--ClientSession(6215763)--Connection(10098848)--Thread(Thread[main,5,main])--UPDATE table_ids SET next_id = next_id + ? WHERE table_id = ?
bind => [5, 10]
[EL Fine]: 2013-01-23 14:08:36.0--ClientSession(6215763)--Connection(10098848)--Thread(Thread[main,5,main])--SELECT next_id FROM table_ids WHERE table_id = ?
bind => [10]
前もって感謝します!