我正在使用IntelliJ下运行的TestNg测试hibernate。 我在套件中有两个测试,当套件运行时,其中一个失败。当我单独运行它们时它们会成功。 此外,当我点击“仅运行失败”时,我会变绿。
我猜测试的主体在这种情况下并不重要,但无论如何我都在这里提出。 Stacktrace在下面。
我尝试将singleThreaded参数添加到测试套件中,但这没有帮助。我还添加了AfterMethod,我认为应该有所帮助,但结果是一样的。 有什么想法正在发生什么?
@Test(singleThreaded = true)
public class RatesPersistanceTest
{
private SessionFactory sessionFactory;
@BeforeMethod
private void before() throws Exception
{
sessionFactory = new Configuration().configure().buildSessionFactory();
}
@AfterMethod
private void after() throws Exception
{
sessionFactory.close();
}
@Test
public void should_save_rates_and_retrieve_them_with_success()
{
Money standardPrice = Money.parse("USD 85");
Money upchargeExtraPerson = Money.parse("USD 80");
Money upchargeExtraBed = Money.parse("USD 75");
Room room = getMeRoom();
AvailabilityPeriod availabilityPeriod = new AvailabilityPeriod(DateTime.now(), DateTime.now().plusDays(5), true);
Season season = new BasicSeason("season name", availabilityPeriod);
Rate seasonRate = new SeasonRate(standardPrice, upchargeExtraPerson, upchargeExtraBed, room, season);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(room);
session.save(season);
session.save(seasonRate);
session.getTransaction().commit();
session.close();
}
@Test(expectedExceptions = org.hibernate.exception.ConstraintViolationException.class)
public void season_rate_should_violate_db_constraints_when_saved_without_season()
{
Money standardPrice = Money.parse("USD 85");
Money upchargeExtraPerson = Money.parse("USD 80");
Money upchargeExtraBed = Money.parse("USD 75");
Room room = getMeRoom();
AvailabilityPeriod availabilityPeriod = new AvailabilityPeriod(DateTime.now(), DateTime.now().plusDays(5), true);
Season season = new BasicSeason("season name", availabilityPeriod);
Rate seasonRate = new SeasonRate(standardPrice, upchargeExtraPerson, upchargeExtraBed, room, null);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(room);
session.save(season);
session.save(seasonRate);
session.getTransaction().commit();
session.close();
}
private Room getMeRoom()
{
final RoomName roomName = new RoomName("101");
final RoomType roomType = new RoomType("cheap");
final Money standardPrice = Money.parse("USD 100");
final Money upchargeExtraPerson = Money.parse("USD 50");
final Money upchargeExtraBed = Money.parse("USD 20");
final RackRate rackRate = new RackRate(standardPrice, upchargeExtraPerson, upchargeExtraBed, null);
final int maxExtraBeds = 2;
final Occupancy occupancy = new Occupancy(4, 2);
return new Room("C", roomName, roomType, rackRate, HousekeepingStatus.CLEAN, RoomAvailability.AVAILABLE, maxExtraBeds, occupancy);
}
}
堆栈跟踪短版本:
org.hibernate.PessimisticLockException: Timeout trying to lock table "ROOMS"; SQL statement:
insert into ROOMS
...
Caused by: org.h2.jdbc.JdbcSQLException: Timeout trying to lock table "ROOMS"; SQL statement:
insert into ROOMS
hibernate config:
<property name="connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=0</property>
<property name="hbm2ddl.auto">create-drop</property>
堆栈跟踪:
org.hibernate.PessimisticLockException: Timeout trying to lock table "ROOMS"; SQL statement:
insert into ROOMS (prefix, housekeepingStatus, availability, typeName, maxExtraBeds, standardPrice, upchargeExtraPerson, upchargeExtraBed, standard, maximum, name) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [50200-168]
at org.hibernate.dialect.H2Dialect$2.convert(H2Dialect.java:317)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at $Proxy9.executeUpdate(Unknown Source)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2962)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3403)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1210)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:399)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at net.mklew.hotelms.persistance.RatesPersistanceTest.should_save_rates_and_retrieve_them_with_success(RatesPersistanceTest.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:673)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:842)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1166)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.runWorkers(TestRunner.java:1178)
at org.testng.TestRunner.privateRun(TestRunner.java:757)
at org.testng.TestRunner.run(TestRunner.java:608)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1158)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1083)
at org.testng.TestNG.run(TestNG.java:999)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:203)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:174)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.h2.jdbc.JdbcSQLException: Timeout trying to lock table "ROOMS"; SQL statement:
insert into ROOMS (prefix, housekeepingStatus, availability, typeName, maxExtraBeds, standardPrice, upchargeExtraPerson, upchargeExtraBed, standard, maximum, name) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [50200-168]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.table.RegularTable.doLock(RegularTable.java:500)
at org.h2.table.RegularTable.lock(RegularTable.java:434)
at org.h2.command.dml.Insert.insertRows(Insert.java:123)
at org.h2.command.dml.Insert.update(Insert.java:84)
at org.h2.command.CommandContainer.update(CommandContainer.java:75)
at org.h2.command.Command.executeUpdate(Command.java:230)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:156)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:142)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
... 47 more
答案 0 :(得分:1)
我回到那个项目,问题也回来了。
解决方案如下:
将@BeforeMethod和@AfterMethod更改为@BeforeSuite和@AfterSuite
这也意味着在一个测试中插入的数据将在另一个测试中可见,至少我认为如果我不在测试之间放下hibernate就是这种情况,但这至少有效,所以我可以处理它。