假设我同时使用Hibernate(JPA)和jOOQ进行数据持久化。
我想通过EntityManager打开事务以做一些工作。
然后我使用jOOQ在我使用EntityManager打开的同一个事务中选择和更新几个表,并提交或回滚上面的所有操作。
我不使用Spring或任何其他容器事务管理器。
try {
entityManager.getTransaction().begin();
//do JPA stuff here fetch from FB update entity
DLSConext - want to use JOOQ DSL for crud operation
em.getTransaction().commit()
} catch (Exception e) {
em.getTransaction().rollback(); //All Hibernate and jooq operation should rool back
}
编辑那么我该怎么做呢?比方说,我使用jOOQ进行一些更新,然后我想让Hibernate找到一个实体,但是我也想让Hibernate在获取一个实体之前看到jOOQ所做的更新。
这并不是jOOQ特有的,但适用于JPA与本机SQL的所有混合。在运行任何jOOQ(或JDBC等)查询之前,您必须确保所有Hibernate的缓存都被刷新。
如果您直接使用jOOQ执行查询,您可以在jOOQ的ConnectionProvider
SPI中执行此操作,每次jOOQ想要执行查询之前,jOOQ都会调用该SPI。或者,使用Hibernate的Session. doWork()
API,如下所示:
public static Work jOOQWork(Session session, Consumer<DSLContext> consumer) {
session.flush();
session.doWork(connection -> consumer.accept(DSL.using(connection)));
}
然后:
jOOQWork(session, ctx ->
ctx.insertInto(TABLE)
.columns(TABLE.COL)
.values(1)
.execute()
);
请注意,这里需要 Session.flush(),
尽管它可能不应该是必需的,请参阅 https://hibernate.atlassian.net/browse/HHH-14209
如果您通过EntityManager::createNativeQuery执行查询,则应自动为您调用
EntityManager::flush
。