2011-07-15 20 views

Respuesta

15

Este será el código específico del proveedor de JPA. Normalmente esto se hace invocando unwrap() en la clase EntityManager.

Si está utilizando EclipseLink, el siguiente código (de la EclipseLink wiki) será útil (en el caso de que utilice una aplicación gestionados EntityManager):

APP 2,0

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

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

Tenga en cuenta, que la solución proporcionada por JPA 2.0 fallará para Hibernate 3.6.5 con un PersistenceException que contiene el mensaje

Hibernate no puede desenvolver interfaz java.sql.Connection

Utilice el código proporcionado por Skaffman a conseguir que funcione contra Hibernate (verificado para trabajar bajo 3.6.5 incluso para contextos de persistencia administrados por contenedor).

Sin embargo, el wiki de EclipseLink señala un poco de información útil: si está utilizando orígenes de datos administrados por JTA, debe inyectarlo usando la anotación @Resource o recuperarlo utilizando una búsqueda JNDI. Siempre que necesite realizar un trabajo transaccional en contra de la base de datos, es irrelevante si está obteniendo una nueva conexión de la fuente de datos o una existente; la mayoría de los grupos de conexiones proporcionarán, de todos modos, la misma conexión que está asociada con el hilo actual (es decir, el que ya utiliza el administrador de entidades). Por lo tanto, evitaría desenvolver al administrador de entidades de esta manera y también realizar actividades transaccionales contra la base de datos; recuerde que el caché de contexto de persistencia y un caché de segundo nivel pueden no sincronizarse si hace esto.

+0

unwrap (java.sql.Connection.class) también no funciona en OpenJPA (al menos 2.1.1) –

+0

@Pawel, que parece estar [ "fijo" en 2.2.0] (https: //issues.apache .org/jira/browse/OPENJPA-1803). –

+0

¡Gracias! sin embargo, no han publicado todavía :) 2.2.0 –

2

que debe tomar el delegado subyacente utilizando entitymanager.getDelegate() o entitymanager.unwrap (que es la mejor manera), echarlo a la implementación específica (en Hibernate se llama Session). Luego puede llamar al método connection(). Tenga en cuenta que esto está en desuso, use la clase Work en su lugar. Leer más here.

7

El propio API JPA no parece ofrecer esto, como es lógico, pero si usted está dispuesto para acoplar el código para una aplicación específica, entonces usted puede usar algo como esto (Hibernate):

Session hibernateSession = entityManager.unwrap(Session.class); 
Connection jdbcConnection = hibernateSession.connection(); 

Tenga en cuenta que Session.connection() está en desuso para su eliminación en Hibernate 4. Considere el uso de Session.doWork() en su lugar.

5

En Hibernate, la solución Publicado por skaffman dio lugar a la siguiente mensaje de error:

Hibernate no puede desenvolver org.hsqldb clase.Sesión

Yo conseguir que funcione utilizando SessionImpl en lugar de la sesión:

Connection connection = entityManager().unwrap(SessionImpl.class).connection(); 

Un ejemplo de solución del problema usando Session.doWork() es la siguiente:

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

    }); 
} 
+0

debe echarlo a "org.hibernate.Session" y no "org.hsqldb.Session" – dulon

1

Este funciona de maravilla y puede usar el objeto de conexión en cualquier otro lugar si es necesario

SessionImpl sessionImpl = (SessionImpl) session; 
Connection conn = sessionImpl.connection(); 

Donde session es el nombre del objeto Sesión de Hibernate

0

A continuación se muestra el código que funcionó para mí. Utilizamos jpa 1.0, la implementación de Apache openjpa.

import java.sql.Connection; 
import org.apache.openjpa.persistence.OpenJPAEntityManager; 
import org.apache.openjpa.persistence.OpenJPAPersistence; 



public final class MsSqlDaoFactory { 


    public static final Connection getConnection(final EntityManager entityManager) { 
      OpenJPAEntityManager openJPAEntityManager = OpenJPAPersistence.cast(entityManager); 
      Connection connection = (Connection) openJPAEntityManager.getConnection(); 
      return connection; 

    } 

} 
0

En JPA2.0, si es necesario JDBC es por nomodel DTO o entidad de consulta más compleja . A veces APP no es todo ...

espero que esto le ayudará a:

Statement statement = null; 
EntityManager em = null; 
em = emf.createEntityManager(); 
EntityTransaction et = em.getTransaction(); 

if(!et.isActive()) { 
    et.begin(); 
} 

java.sql.Connection connection = em.unwrap(java.sql.Connection.class); 

    String qquerry="SELE ... 
    try { 
     statement = connection.createStatement(); 
     ResultSet rs = statement.executeQuery(qquerry);                

     if (!rs.next()) { 
      return null; 
     } 
     else{ 
      wwwwas=rs.getString(4);         
     }   
     statement.close(); 
     } 
    catch (SQLException e) { 
     System.out.println("\n b-03:"+e); 
     throw new RuntimeException(e.getMessage(), e); 
    } 
    finally { 
     try { 
      // em.getTransaction().commit(); 
      if(connection != null) 
      connection.close(); 
     } 
     catch (Exception e) { 
      throw new RuntimeException(e.getMessage(), e); 
     } 
    } 
Cuestiones relacionadas