J'ai une application de travail où j'utilise Java EE 6 avec EclipseLink pour la persistance et une base de données PostgreSQL.
Pour l'enregistrement d'utilisateur, je veux définir le mot de passe dans PostgreSQL pour:
... password = crypt('inputPassword',gen_salt('bf')) ...
Comme je ne peux pas utiliser DigestUtils pour cela, je dois insérer l'utilisateur manuellement dans la base de données. Pour que mon application reste configurable, je ne souhaite pas interroger le DataSource avec un InitialContextInstance.lookup(dataSource)
mais l'extraire ( ou la connexion) en quelque sorte de EntityManager comme:
DataSource ds = entityManagerInstance.someFunctionThatReturnsADataSourceOrConnection();
Ou serait-il possible d'utiliser createNativeQuery ou quelque chose de similaire en conjonction Avec une déclaration préparée pour se protéger contre les injections?
parfois, il faut juste une autre course dans google:
entityManager.getTransaction().begin();
Java.sql.Connection connection = entityManager.unwrap(Java.sql.Connection.class);
...
entityManager.getTransaction().commit();
comme décrit dans Eclipse Link Documentation
En réponse au commentaire "Archimedes Trajano" sur la réponse acceptée, la réponse acceptée fonctionne-t-elle pour autre chose qu'Eclipselink? La réponse est non pour au moins Hibernate.
J'ai eu l'erreur suivante lorsque j'ai essayé la réponse acceptée pour mettre en veille prolongée:
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]
Une combinaison de réponses aux questions de stackoverflow suivantes m'a permis de proposer une solution qui fonctionne pour Hibernate.
Obtenez un objet de connexion JDBC à partir d'un bean sans état
Objet Hibernate get Connection pour JasperRunManager
Voici ma solution:
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
}
});
Voici un extrait de code qui fonctionne avec Hibernate 4, basé sur la réponse de dulon
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;
}
}