2011-07-15 24 views

Trả lời

15

Đây sẽ là mã dành riêng cho nhà cung cấp JPA. Thông thường, điều này được thực hiện bằng cách gọi unwrap() trên lớp EntityManager.

Nếu bạn đang sử dụng EclipseLink, đoạn code sau (từ EclipseLink wiki) sẽ hữu ích (trong trường hợp bạn đang sử dụng một ứng dụng quản lý EntityManager):

JPA 2,0

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

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

Lưu ý rằng giải pháp cung cấp cho JPA 2.0 sẽ thất bại cho Hibernate 3.6.5 với một PersistenceException chứa thông điệp

Hibernate không thể unwrap giao diện java.sql.Connection

Sử dụng mã được cung cấp bởi Skaffman để làm cho nó làm việc chống lại Hibernate (xác minh để làm việc dưới 3.6.5 ngay cả đối với các bối cảnh liên tục quản lý container). Tuy nhiên, EclipseLink wiki chỉ ra một bit thông tin hữu ích - nếu bạn đang sử dụng các nguồn dữ liệu được quản lý JTA, bạn nên tiêm nó bằng cách sử dụng chú thích @Resource hoặc truy xuất chú thích bằng cách sử dụng tra cứu JNDI. Miễn là bạn cần thực hiện công việc giao dịch đối với cơ sở dữ liệu, việc bạn có được kết nối mới từ nguồn dữ liệu hay dữ liệu hiện có là không quan trọng; hầu hết các nhóm kết nối sẽ cung cấp cùng một kết nối được kết hợp với luồng hiện tại (tức là một kết nối đã được trình quản lý thực thể sử dụng). Do đó, bạn sẽ tránh unwrapping quản lý thực thể theo cách này, và cũng thực hiện hoạt động giao dịch đối với cơ sở dữ liệu; hãy nhớ rằng bộ nhớ cache bối cảnh bền bỉ và bộ nhớ cache cấp hai có thể không được đồng bộ hóa nếu bạn thực hiện việc này.

+0

unwrap (java.sql.Connection.class) cũng không hoạt động trong OpenJPA (ít nhất 2.1.1) –

+0

@Pawel, nó có vẻ là ["cố định" trong 2.2.0] (https: //issues.apache .org/jira/duyệt/OPENJPA-1803). –

+0

Cảm ơn bạn! nhưng họ chưa phát hành 2.2.0 chưa :) –

2

Bạn phải chọn người đại diện cơ bản bằng cách sử dụng entitymanager.getDelegate() hoặc entitymanager.unwrap (cách tốt hơn), đưa nó vào triển khai cụ thể (trong Hibernate được gọi là Session). Sau đó, bạn có thể gọi phương thức connection(). Lưu ý rằng điều này không được dùng nữa, thay vào đó hãy sử dụng lớp Work. Đọc thêm here.

7

Các JPA API chính nó dường như không cung cấp này, không đáng ngạc nhiên, nhưng nếu bạn sẵn sàng vài mã của bạn để thực hiện cụ thể, sau đó bạn có thể sử dụng một cái gì đó như thế này (Hibernate):

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

Lưu ý rằng Session.connection() không còn được dùng để xóa trong Hibernate 4. Thay vào đó, hãy cân nhắc sử dụng Session.doWork().

5

Trong Hibernate, giải pháp đăng bởi skaffman dẫn đến thông báo lỗi sau:

Hibernate không thể unwrap lớp org.hsqldb.Phiên

tôi đã làm cho nó hoạt sử dụng SessionImpl chứ không phải là phiên:

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

Một ví dụ về giải quyết vấn đề sử dụng Session.doWork() như sau:

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

bạn nên bỏ nó vào "org.hibernate.Session" và không "org.hsqldb.Session" – dulon

1

này hoạt động awesomely và bạn có thể sử dụng đối tượng kết nối ở nơi khác nếu cần

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

Trường hợp session là tên của đối tượng Phiên làm việc Hibernate

0

Dưới đây là mã làm việc cho tôi. Chúng tôi sử dụng jpa 1.0, triển khai thực hiện 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

Trong JPA2.0, nếu cần JDBC là por DTO nomodel hay tổ chức nào cho truy vấn hơn phức tạp. Đôi khi JPA là không phải tất cả ...

Tôi hy vọng điều này sẽ giúp bạn:

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); 
     } 
    } 
Các vấn đề liên quan