テストデータベースとしてインメモリHSQLデータベースを使用してデータベース依存コードのユニットテストを頻繁に書き込みます。最近、1.8.1.3から2.2.9にアップグレードし、2.xリリースブランチで追加されたROW_NUMBER()サポートを利用することに決めました。hsqldb 1.8.1.3上のHibernateベースコードのユニットテストhsqldb 2.2.9
何らかの形で新しいバージョンが古いバージョンよりも厳しいようです。 ORMとしてHibernate(3.6.10)を使用すると、最初にSessionFactory
を作成するためにConfiguration
オブジェクトを作成し、それを使用してテストデータを生成した後、テスト対象のクラスにConfiguration
を使用して、自分自身を作成しますSessionFactory
選択。 hsqldb 1.8.1.3では問題ありません。 2.2.9では、selectブロックはhsqldbコードの内部にあります。以下は、このことを証明するSSCCEです:
public void testTwoSessionFactories() throws Exception {
boolean withTx = false;
AnnotationConfiguration config = new AnnotationConfiguration().addAnnotatedClass(Entity.class);
config.setProperty("hibernate.hbm2ddl.auto", "create");
config.setProperty(Environment.DIALECT, HSQLDialect.class.getName());
config.setProperty(Environment.DRIVER, jdbcDriver.class.getName());
config.setProperty(Environment.URL, "jdbc:hsqldb:mem:testDB");
config.setProperty(Environment.USER, "SA");
config.setProperty(Environment.PASS, "");
SessionFactory sessionFactory1 = config.buildSessionFactory();
Session session = sessionFactory1.openSession();
Transaction tx = null;
if (withTx)
tx = session.beginTransaction();
session.save(new Entity("one"));
if (withTx)
tx.commit();
session.flush();
session.close();
config.setProperty("hibernate.hbm2ddl.auto", "");
SessionFactory sessionFactory2 = config.buildSessionFactory();
Session session2 = sessionFactory2.openSession();
List entities = session2.createCriteria(Entity.class).list();
session2.close();
}
withTx
ブール値に注意してください。 HSQLDB 1.8.1.3では、このコードをwithTx
trueまたはfalseで実行できます。これは問題ありません。
Unsafe.park(boolean, long) line: not available [native method]
LockSupport.park(Object) line: not available
CountDownLatch$Sync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line: not available
CountDownLatch$Sync(AbstractQueuedSynchronizer).doAcquireSharedInterruptibly(int) line: not available
CountDownLatch$Sync(AbstractQueuedSynchronizer).acquireSharedInterruptibly(int) line: not available
CountDownLatch.await() line: not available
CountUpDownLatch.await() line: not available
Session.executeCompiledStatement(Statement, Object[]) line: not available
Session.execute(Result) line: not available
JDBCPreparedStatement.fetchResult() line: not available
JDBCPreparedStatement.executeQuery() line: not available
BatchingBatcher(AbstractBatcher).getResultSet(PreparedStatement) line: 208
CriteriaLoader(Loader).getResultSet(PreparedStatement, boolean, boolean, RowSelection, SessionImplementor) line: 1953
CriteriaLoader(Loader).doQuery(SessionImplementor, QueryParameters, boolean) line: 802
CriteriaLoader(Loader).doQueryAndInitializeNonLazyCollections(SessionImplementor, QueryParameters, boolean) line: 274
CriteriaLoader(Loader).doList(SessionImplementor, QueryParameters) line: 2542
CriteriaLoader(Loader).listIgnoreQueryCache(SessionImplementor, QueryParameters) line: 2276
CriteriaLoader(Loader).list(SessionImplementor, QueryParameters, Set, Type[]) line: 2271
CriteriaLoader.list(SessionImplementor) line: 119
SessionImpl.list(CriteriaImpl) line: 1716
CriteriaImpl.list() line: 347
EntityTest.testTwoSessionFactories() line: 46
必要と1.8.1.3と2.2.9の間でHSQLDBで何が変わった:HSQLDB 2.2.9では、withTx
は、そうでない場合、スレッドは、以下のスタックと.list()
呼び出しでブロックされる、真に設定する必要があります。このコードは、トランザクション内で保存を行うために、私はそれをオフにすることができますか?
HSQLDBを開発している人に質問してください。 –
すべてのデータベースのやりとりは、トランザクション内で実行する必要があります。これが、Hibernateのドキュメントが推奨するものです。私はバグを修正し、常にトランザクションを使用するようにします。また、なぜ2つの異なるセッションファクトリを使用していますか?それをする理由はありません。セッションファクトリは、一度作成しなければならない重量のあるオブジェクトです。クリアユニットテストの場合+1。 –
@JBNizet Re:プロダクションコードのトランザクション私はいつもそうしていますが、テストセットアップコードでは、テストに混乱を招くだけだと思っています。それほど悪くない私はそれを変更することはできません! – sharakan