如何从Java EE 6中的JPA2 EntityManager获取DataSource或Connection

我有一个工作的应用程序,我使用Java EE 6与EclipseLink进行持久化和PostgreSQL数据库。

对于User-Registration,我想在PostgreSQL中将密码设置为:

... password = crypt('inputPassword',gen_salt('bf')) ... 

由于我不能使用DigestUtils,我必须手动将用户插入数据库。 为了保持我的应用程序可配置,我不想使用InitialContextInstance.lookup(dataSource)查询DataSource,而是以某种方式从EntityManager中提取它(或连接),如:

 DataSource ds = entityManagerInstance.someFunctionThatReturnsADataSourceOrConnection(); 

或者是否可以使用createNativeQuery或类似的东西与预备语句结合以防止注入?

有时它只需要在谷歌另一次运行:

 entityManager.getTransaction().begin(); java.sql.Connection connection = entityManager.unwrap(java.sql.Connection.class); ... entityManager.getTransaction().commit(); 

如Eclipse链接文档中所述

为回应“阿基米德·特拉哈诺”对接受的答案的评论,接受的答案是否适用于除Eclipselink以外的其他人? 至少Hibernate的答案是否定的。

当我尝试接受hibernate的答案时,我收到以下错误:

 Caused by: org.springframework.orm.jpa.JpaSystemException: Hibernate cannot unwrap interface java.sql.Connection; nested exception is javax.persistence.PersistenceException: Hibernate cannot unwrap interface java.sql.Connection at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:418) ~[spring-orm-4.0.5.RELEASE.jar:4.0.5.RELEASE] 

以下stackoverflow问题的答案组合使我能够提出适用于Hibernate的解决方案。

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

Hibernate获取JasperRunManager的Connection对象

这是我的解决方案:

  Session hibernateSession = entityManager.unwrap(Session.class); hibernateSession.doWork(new org.hibernate.jdbc.Work() { @Override public void execute(Connection connection) throws SQLException { // do whatever you need to do with the connection } }); 

这是基于dulon的答案,与Hibernate 4一起使用的代码片段

 Connection getConnection() { Session session = entityManager.unwrap(Session.class); MyWork myWork = new MyWork(); session.doWork(myWork); return myWork.getConnection(); } private static class MyWork implements Work { Connection conn; @Override public void execute(Connection arg0) throws SQLException { this.conn = arg0; } Connection getConnection() { return conn; } }