3

最近、永続化プロバイダーを 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]

前もって感謝します!

4

1 に答える 1

1

問題は更新と選択の順序ではなく、現在の値を持つかどうかの解釈です。EclipseLink は現在の値を取得すると想定していますが、OpenJPA はそうではないようです。

理想的には、非 JPA の使用法を変更して同じ仮定を行うことができます。それができない場合は、EclipseLink で独自のカスタム Sequence オブジェクトを作成できます。

これを行うには、TableSequence のサブクラスを作成し、buildSelectQuery() メソッドをオーバーライドして SQL に「+ 1」(または「- 1」) を追加し、仮定の違いを説明します。

その後、SessionCustomizer を使用してカスタム シーケンスを追加できます。

また、EclipseLink にバグを記録して、OpenJPA シーケンス用の互換性オプションを追加してください。

于 2013-01-30T14:43:04.550 に答える