Tôi thường xuyên viết các bài kiểm tra đơn vị mã phụ thuộc cơ sở dữ liệu của tôi bằng cơ sở dữ liệu HSQL trong bộ nhớ làm cơ sở dữ liệu thử nghiệm. Gần đây tôi đã quyết định nâng cấp từ 1.8.1.3 lên 2.2.9 để tận dụng lợi thế của ROW_NUMBER() hỗ trợ đã được thêm vào trong nhánh phát hành 2.x.Kiểm tra đơn vị mã dựa trên Hibernate trên đầu trang của hsqldb 1.8.1.3 không còn hoạt động trên hsqldb 2.2.9
Dường như, theo một cách nào đó, phiên bản mới nghiêm ngặt hơn phiên bản cũ. Sử dụng Hibernate (3.6.10) làm ORM, tôi có thể tạo một đối tượng Configuration
để tạo SessionFactory
đầu tiên, sử dụng để điền dữ liệu thử nghiệm, sau đó sử dụng Configuration
cho lớp đang thử nghiệm, tạo ra nó SessionFactory
để làm một lựa chọn. Với hsqldb 1.8.1.3, không sao cả. Với 2.2.9, các khối chọn bên trong mã hsqldb. Bên dưới là SSCCE chứng minh điều này:
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();
}
Lưu ý withTx
boolean. Với HSQLDB 1.8.1.3, tôi có thể chạy mã này với withTx
đúng hoặc sai, và nó sẽ ổn. Với HSQLDB 2.2.9, withTx
phải được thiết lập là true, nếu không sợi bị chặn trong các cuộc gọi .list()
với chồng sau:
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
gì thay đổi trong HSQLDB giữa 1.8.1.3 và 2.2.9 mà đòi hỏi mã này để thực hiện lưu trong giao dịch và tôi có thể tắt nó không?
Có thể bạn nên yêu cầu những người phát triển HSQLDB. –
Mọi tương tác cơ sở dữ liệu phải được thực hiện bên trong một giao dịch. Đó là những gì tài liệu Hibernate đề xuất. Tôi chỉ đơn giản là sửa lỗi và đảm bảo bạn luôn sử dụng giao dịch. Ngoài ra, tại sao bạn sử dụng hai nhà máy phiên khác nhau? Không có lý do để làm điều đó. Nhà máy phiên là một đối tượng hạng nặng cần được tạo một lần và cho tất cả. 1 cho thử nghiệm đơn vị rõ ràng. –
@JBNizet Re: các giao dịch, trong mã sản xuất Tôi luôn làm điều đó, nhưng trong thử nghiệm thiết lập mã tôi looser bởi vì tôi nghĩ rằng nó chỉ thêm lộn xộn để kiểm tra. Không tệ đến mức tôi không thể thay đổi nó được! – sharakan