从无状态Bean中获取JDBC Connection对象

Rad*_*scu 12 java hibernate ejb jpa jdbc

在无状态会话Bean EntityManager中注入了一个但是我想获取一个Connection对象以调用DB过程.这有什么解决方案吗?

Vin*_*lds 16

这将是JPA提供商特定的代码.通常,这是通过调用完成unwrap()EntityManager类.

如果您使用的是EclipseLink,则以下代码(来自EclipseLink wiki)将非常有用(如果您使用的是应用程序管理的EntityManager):

JPA 2.0

entityManager.getTransaction().begin();
java.sql.Connection connection = entityManager.unwrap(java.sql.Connection.class); // unwraps the Connection class.
...
entityManager.getTransaction().commit();
Run Code Online (Sandbox Code Playgroud)

JPA 1.0

entityManager.getTransaction().begin();
UnitOfWork unitOfWork = (UnitOfWork)((JpaEntityManager)entityManager.getDelegate()).getActiveSession();
unitOfWork.beginEarlyTransaction();
Accessor accessor = unitOfWork.getAccessor();
accessor.incrementCallCount(unitOfWork.getParent());
accessor.decrementCallCount();
java.sql.Connection connection = accessor.getConnection();
...
entityManager.getTransaction().commit();
Run Code Online (Sandbox Code Playgroud)

请注意,为PersistenceException包含该消息的Hibernate 3.6.5提供的JPA 2.0解决方案将失败

Hibernate无法解开java.sql.Connection接口

使用Skaffman提供的代码使其与Hibernate一起工作(即使对于容器管理的持久性上下文,也验证了在3.6.5下工作).

但是,EclipseLink wiki指出了一些有用的信息 - 如果您使用的是JTA托管数据源,则应该使用@Resource注释注入它或使用JNDI查找检索它.只要您需要对数据库执行事务性工作,无论您是从数据源还是从现有数据源获取新连接,都是无关紧要的; 无论如何,大多数连接池都将提供与当前线程相关联的相同连接(即实体管理器已经使用的连接).因此,您可以避免以这种方式展开实体管理器,还可以对数据库执行事务活动; 请记住,如果执行此操作,可能无法同步持久性上下文缓存和二级缓存.


Mar*_*man 11

在Hibernate中,skaffman发布的解决方案导致以下错误消息:

Hibernate无法解包org.hsqldb.Session类

我确实使用SessionImpl而不是Session来使用它:

Connection connection = entityManager().unwrap(SessionImpl.class).connection();
Run Code Online (Sandbox Code Playgroud)

使用Session.doWork()解决问题的示例如下:

private void executeNative(final String query) {
    Session session = entityManager.unwrap(Session.class);
    session.doWork(new Work() {

        @Override
        public void execute(Connection connection) throws SQLException {
            Statement s = null;
            try {
                s = connection.createStatement();
                s.executeUpdate(query);
            } 
            finally {
                if (s != null) {
                    s.close();
                }
            }
        }

    });
}
Run Code Online (Sandbox Code Playgroud)


ska*_*man 7

JPA API本身似乎没有提供这一点,这并不奇怪,但如果您愿意将代码耦合到特定的实现,那么您可以使用类似的东西(Hibernate):

Session hibernateSession = entityManager.unwrap(Session.class);
Connection jdbcConnection = hibernateSession.connection(); 
Run Code Online (Sandbox Code Playgroud)

请注意,Session.connection()在Hibernate 4中不推荐删除.请考虑使用Session.doWork().