在一个事务中组合JPA和JDBC操作

所以,我有一个带有一些遗留JDBC调用的应用程序,我需要使用一些额外的JPA操作进行更新。 我需要能够将JDBC调用和JPA调用作为同一数据库事务的一部分。 我正在使用OpenJPA 2.1.1和Postgres 9.1,如果重要的话。 以下代码似乎正常工作 – 我运行了一些基本测试,并且JDBC和JPA语句都执行; 任何一个中的错误都会导致这对语句没有发生(例如,它们是同一个DB事务的一部分)。 它是否有任何我没有看到的问题 – 我违反了一些最佳实践,或者其他原因我不能以这种方式重新使用Connection对象?

EntityManager em = _em; //acquired from OpenJPA em.getTransaction().begin(); Connection conn; try { OpenJPAEntityManager oem = (OpenJPAEntityManager) em.getDelegate(); conn = oem.getConnection(); PreparedStatement ps = conn.prepareStatement(myStatement); //initialize parameters in ps ps.executeUpdate(); em.merge(myJpaObject); em.getTransaction().commit(); } finally { if (ps != null && !ps.isClosed()) { ps.close(); } if (em.getTransaction().isActive()) { em.getTransaction().rollback(); } } 

谢谢!

通过一次调整,我认为应该没问题。

值得注意的是OpenJPA文档对此有何评论 :

如果EntityManager处于托管或非乐观事务中,如果EntityManager已在当前事务中刷新,或者您已使用OpenJPAEntityManager.beginStore方法确保返回连接,则仅保证返回的连接与其他EntityManager操作在事务上保持一致数据存储区事务正在进行中。 始终在尝试任何其他EntityManager操作之前关闭返回的连接。 OpenJPA将确保在数据存储区事务正在进行时不会释放基础本机连接。

您的交易不受管理,但我认为这不是乐观的。 此外,在启动事务和执行JDBC操作之间,您还没有完成任何JPA工作,因此我认为您可能属于“如果EntityManager在当前事务中已刷新”的情况。

你没有做的一件事就是在继续使用JPA之前关闭连接。 我假设OpenJPA没有返回它正在使用的实际连接,但是在OpenJPA恢复工作之前应该关闭它的一些包装器。