我如何 "obtain transaction-synchronized Session for current thread" 在 Micronaut / Kotest / Hibernate 测试中
How do I "obtain transaction-synchronized Session for current thread" in a Micronaut / Kotest / Hibernate test
我正在尝试在每次测试后清理我的组件测试使用的数据库,以便下一次测试时该数据库为空。为此,我有如下内容:
@MicronautTest
class ExampleTest(
private val entityManager: EntityManager
) : BehaviorSpec() {
override fun afterEach(testCase: TestCase, result: TestResult) {
entityManager.transaction.begin()
entityManager.createQuery("delete from DeviceEntity").executeUpdate()
ementityManagertransaction.commit()
entityManager.clear()
}
/* test code */
}
然而,当我 运行 这样做时,我得到以下错误:
Could not obtain transaction-synchronized Session for current thread
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at io.micronaut.transaction.hibernate5.MicronautSessionContext.currentSession(MicronautSessionContext.java:100)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:479)
at io.micronaut.configuration.hibernate.jpa.TransactionalSessionInterceptor.intercept(TransactionalSessionInterceptor.java:56)
at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:82)
at io.micronaut.configuration.hibernate.jpa.TransactionalSession$Intercepted.unwrap(Unknown Source)
at uk.arqit.cloud.device.core.service.v1.services.component.example.ExampeTest.afterEach(IncrementRatchetSuccessTest.kt:56)
...
我在其他帖子中看到提到使用 @Transaction
来修饰方法或从会话工厂获取实体管理器,但是使用这些时错误是相同的。
运行在我的测试的 init { ... }
子句中使用此代码没有问题(即测试代码所在的位置),并且它完全按预期工作。但是如果我 运行 它在 afterEach
它有一个问题。
任何人都可以就如何解决这个问题提供一些建议吗?
谢谢!
找到解决方案,首先将SessionFactory
添加到构造函数中:
@MicronautTest
class ExampleTest(
private val entityManager: EntityManager,
private val sessionFactory: SessionFactory
) : BehaviorSpec() {
afterEach(...) {
...
}
}
在afterEach
方法中有以下内容:
override fun afterEach(testCase: TestCase, result: TestResult) {
val sesh = sessionFactory.openSession()
val em = sesh.entityManagerFactory.createEntityManager()
/* do whatever you want with 'em' */
}
值得一提的是,您还可以在 class 正文中声明 sesh
和 em
,以便它们可以通过所有方法访问
我正在尝试在每次测试后清理我的组件测试使用的数据库,以便下一次测试时该数据库为空。为此,我有如下内容:
@MicronautTest
class ExampleTest(
private val entityManager: EntityManager
) : BehaviorSpec() {
override fun afterEach(testCase: TestCase, result: TestResult) {
entityManager.transaction.begin()
entityManager.createQuery("delete from DeviceEntity").executeUpdate()
ementityManagertransaction.commit()
entityManager.clear()
}
/* test code */
}
然而,当我 运行 这样做时,我得到以下错误:
Could not obtain transaction-synchronized Session for current thread
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at io.micronaut.transaction.hibernate5.MicronautSessionContext.currentSession(MicronautSessionContext.java:100)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:479)
at io.micronaut.configuration.hibernate.jpa.TransactionalSessionInterceptor.intercept(TransactionalSessionInterceptor.java:56)
at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:82)
at io.micronaut.configuration.hibernate.jpa.TransactionalSession$Intercepted.unwrap(Unknown Source)
at uk.arqit.cloud.device.core.service.v1.services.component.example.ExampeTest.afterEach(IncrementRatchetSuccessTest.kt:56)
...
我在其他帖子中看到提到使用 @Transaction
来修饰方法或从会话工厂获取实体管理器,但是使用这些时错误是相同的。
运行在我的测试的 init { ... }
子句中使用此代码没有问题(即测试代码所在的位置),并且它完全按预期工作。但是如果我 运行 它在 afterEach
它有一个问题。
任何人都可以就如何解决这个问题提供一些建议吗?
谢谢!
找到解决方案,首先将SessionFactory
添加到构造函数中:
@MicronautTest
class ExampleTest(
private val entityManager: EntityManager,
private val sessionFactory: SessionFactory
) : BehaviorSpec() {
afterEach(...) {
...
}
}
在afterEach
方法中有以下内容:
override fun afterEach(testCase: TestCase, result: TestResult) {
val sesh = sessionFactory.openSession()
val em = sesh.entityManagerFactory.createEntityManager()
/* do whatever you want with 'em' */
}
值得一提的是,您还可以在 class 正文中声明 sesh
和 em
,以便它们可以通过所有方法访问