在一个事务中组合JPA和JDBC操作 [英] Combining JPA and JDBC actions in one transaction

查看:578
本文介绍了在一个事务中组合JPA和JDBC操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So, I have an application with some legacy JDBC calls in it that I need to update with some additional JPA actions. I need to be able to make both JDBC calls and JPA calls as part of the same DB transaction. I'm using OpenJPA 2.1.1 and Postgres 9.1, if it matters. The following code appears to work correctly - I've run some basic tests, and both the JDBC and JPA statements execute; an error in either one results in the pair of statements not happening (e.g. they're part of the same DB transaction). Are there any problems with it that I'm not seeing - some best practice that I'm violating, or some other reason I can't re-use the Connection object in this manner?

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();
  }
}

谢谢!

推荐答案

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

With one tweak, i think that should be fine.

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


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

The returned connection is only guaranteed to be transactionally consistent with other EntityManager operations if the EntityManager is in a managed or non-optimistic transaction, if the EntityManager has flushed in the current transaction, or if you have used the OpenJPAEntityManager.beginStore method to ensure that a datastore transaction is in progress. Always close the returned connection before attempting any other EntityManager operations. OpenJPA will ensure that the underlying native connection is not released if a datastore transaction is in progress.

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

Your transaction is not managed, but it is, i think, non-optimistic. Also, you haven't done any JPA work between starting the transaction and doing the JDBC stuff, so i think you probably fall under the "if the EntityManager has flushed in the current transaction" case.

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

The one thing you're not doing is closing the connection before carrying on with JPA. I assume that OpenJPA doesn't return the actual connection it's using, but some wrapper round it which should be closed before OpenJPA resumes work.

这篇关于在一个事务中组合JPA和JDBC操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆