6

JUnit、OpenEJB、Eclipselink、HSQLDBを使用したテストフレームワークがあります。これまでのところすべてが正常に機能しており、サービス層のテストは簡単です。ただし、現在、テーブルで一括インポートを実行する場合(service-tier、entitymanagerを使用)、またはたとえばサービスメソッドでエンティティをリストに複数回永続化する場合に問題が発生します。

これは奇妙な部分です:テストがMavenのコマンドラインから十分に高速なワークステーションで実行された場合にのみ、テストが失敗するようです。Eclipse IDEを介してテストを実行すると、すべてが正常ですが、ランダムに失敗することもあります。テストの実行速度と関係があるのではないかと思われますが、奇妙に聞こえます。基本的に、既存のIDを持つエンティティを追加しようとしていることを示しているため、例外は十分に単純です。テストデータとhsqldbデータベースを何度もチェックしました。使用しようとしているIDを持つ既存の行はありません。それでも、hsqldbはある時点で主キー例外をスローします。ログから、競合するIDが常に同じであるとは限らず、300015または300008である可能性があることがわかります。

私たちはここで終わりを迎えています。HSQLDBのトランザクションや、古いデータを引き起こす他の何かと関係があるのでしょうか?

HSQLDB 2.2.8、Eclipselink 2.3.0、OpenEJB4.0.0-beta2を使用しています。

エンティティを追加しようとしているリレーションは、次のようにマップされます。

@OneToMany(mappedBy = "invoice", cascade = CascadeType.PERSIST)
private List<InvoiceBalance> getInvoiceBalanceHistory() {
    if (invoiceBalanceHistory == null) {
        this.invoiceBalanceHistory = new ArrayList<InvoiceBalance>();
    }
    return invoiceBalanceHistory;
}

ルート例外は次のとおりです。

Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: unique constraint or index violation; SYS_PK_10492 table: INVOICEBALANCE
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:831)
... 82 more
Caused by: org.hsqldb.HsqlException: integrity constraint violation: unique constraint or   index violation; SYS_PK_10492 table: INVOICEBALANCE
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.Constraint.getException(Unknown Source)
at org.hsqldb.index.IndexAVLMemory.insert(Unknown Source)
at org.hsqldb.persist.RowStoreAVL.indexRow(Unknown Source)
at org.hsqldb.TransactionManager2PL.addInsertAction(Unknown Source)
at org.hsqldb.Session.addInsertAction(Unknown Source)
at org.hsqldb.Table.insertSingleRow(Unknown Source)
at org.hsqldb.StatementDML.insertSingleRow(Unknown Source)
at org.hsqldb.StatementInsert.getResult(Unknown Source)
at org.hsqldb.StatementDMQL.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)

編集:

主キー生成戦略をGenerationType.AUTO(デフォルトでTABLE戦略を使用しているようです)からIDENTITYに変更しました。この後、私たちの質量は確実に機能しているように見えます。HSQLDBがTABLE-strategyと「同期しなくなった」理由はまだわかりません。テストフレームワークにバグがあるという理由だけで、jpaエンティティを変更したくありません:)

4

3 に答える 3

0

比較的高速なプラットフォームで、または場合によっては、allocationSize がボトルネックを定義している可能性があります。つまり、GenerationType.AUTO にデフォルト設定されている場合、これはテーブルにデフォルト設定されており、EclipseLink は割り当てられた値まで ID をキャッシュします。次に、ジェネレーターを検索して、最後に割り当てられた値を確認します。ID の次のセットがキャッシュされる前に、allocationSize の端でルックアップが発生した場合、Eclipse リンクがキャッシュ内の最後の ID を 2 回割り当ててから、キャッシュを更新し、両方を挿入に使用しようとするという競合状態に陥る可能性があります。両方の挿入が失敗し、ロールバックされます。可能であれば、割り当てキャッシュをインクリメントする必要があるときにこれが発生するかどうかを確認する必要がありますが、おそらくそのようなチェックにより動作が変わる可能性があります

于 2014-03-13T19:04:10.873 に答える
0

MEMORY多くの場合、多くの行をテーブルにインポートしているときにメモリが不足しています。

メモリ割り当てを増やすか、この特定のテーブルをテーブルとして定義する必要がありCACHEDます。

更新:CACHEDテーブルは、オールインメモリ データベースではなく、永続データベースで使用できます。

CREATE CACHED TABLE mytable ...

または既存のテーブルの場合:

SET TABLE mytable TYPE CACHED

アップデート:

これが OOM によるものではない場合、生成戦略の変更で確認できるように、生成戦略が生成された主キーの値をある時点でインクリメントしていないように思われます。ID 戦略はデータベースに依存して生成された値を作成しますが、これは正常に機能します。

于 2012-04-16T11:02:07.933 に答える
0

integrity constraint violation: unique constraint or index violation デバッガー フリークの場合は、デバッグ モードで hsqldb を再構築し、ブレークポイントの条件で変数が割り当てられている行にブレークポイントを設定org.hsqldb.index.IndexAVLMemory#insertできcompareますcompare == 0

障害のある行 (たとえば、重複する行) は、引数として渡される行になります。

于 2016-06-10T14:51:58.873 に答える