JUnit、OpenEJB、Eclipselink、およびHSQLDBを使用したテストフレームワークがあります。これまでのところすべてがうまくいき、サービス層のテストは簡単です。しかし、今度は、テーブル(サービス層、entitymanagerを使用)で大量インポートを行うときや、サービスメソッドで複数のエンティティをリストに永続化するときに問題が発生しています。JUnitテストにおけるHSQLDB主キー違反エラー
これはWEIRD PARTです:テストがMavenのコマンドラインから十分に速いワークステーションで実行されていれば、私たちのテストは壊れそうです。 Eclipse IDEでテストを実行すると、すべてが正常ですが、ランダムに、失敗することもあります。私たちは、テストが実行されるスピードと何かが関係するかもしれないと思っています。基本的に、すでに存在するidを持つエンティティを追加しようとしているので、例外は十分に簡単です。テストデータとhsqldbデータベースを複数回チェックしました。私たちが使用しようとしているidを持つ既存の行はありません。それでもhsqldbはある時点で主キーの例外をスローします。私たちのログから、競合するIDは必ずしも同じではないことがわかります。300015または300008かもしれません。
私たちはここにいます。 HSQLDBのトランザクションや何か他のものが失効したデータの原因となることがありますか?
HSQLDB 2.2.8、Eclipselink 2.3.0、およびOpenEJB 4.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)
EDIT:
私は主キーの生成方法を変更しましたGenerationType.AUTO(デフォルトでTABLE戦略を使用していると思われる)からIDENTITYこの後も、私たちの大衆は引き続き成功するようです。私はまだHSQLDBがなぜTABLE戦略と「同期していない」のかは分かりません。私たちのテストフレームワークがバグであるからといって、私はjpaのエンティティを変更したくないでしょう:)
どのようなバージョンのHSQLDBを使用していますか? JUnitはデータベースに大きなトランザクション・ロールバック・ロードを課すため、おそらくバグや、HSQLDBを高速かつ小規模に保つために行われた既知のエンジニアリング・トレードオフのいずれかに陥っているでしょう。データベース設定とEclipselinkがIDテーブルを構成し管理する方法の組み合わせかもしれません。常にバージョン番号を投稿することをお勧めします。 –
バージョン番号を元の投稿に編集します。私はHSQLDB 2.2.8 Eclipselink 2.3.0とOpenEJB 4.0.0-beta2を使用しています。また、EntityはIDENTITYカラムを使用していません。代わりに、戦略はAUTOで、これはHSQLDBのTABLE戦略を使用していると思います。 –
問題を見つけて対処するのにどれだけ気を配っていますか? TABLE(またはEclipselinkのTABLEであるAUTO)からSequenceまたはIDENTITYに切り替えると、おそらくこの問題が解消されます。なぜ起こっているのかを理解するには、トランザクションと隔離とロールバックの設定とバグのキャッシングなどの苦しい掘り下げが必要です。 –