2012-11-21 27 views
5

Vì vậy, tôi có một ứng dụng với một số cuộc gọi JDBC kế thừa trong đó mà tôi cần cập nhật với một số hành động JPA bổ sung. Tôi cần có khả năng thực hiện cả các cuộc gọi JDBC và các cuộc gọi JPA như một phần của cùng một giao dịch DB. Tôi đang sử dụng OpenJPA 2.1.1 và Postgres 9.1, nếu nó quan trọng. Đoạn mã sau xuất hiện để hoạt động chính xác - Tôi đã chạy một số kiểm tra cơ bản, và cả câu lệnh JDBC và JPA đều thực thi; một lỗi trong một kết quả trong cặp câu lệnh không xảy ra (ví dụ: chúng là một phần của cùng một giao dịch DB). Có bất kỳ vấn đề với nó mà tôi không nhìn thấy - một số thực hành tốt nhất mà tôi đang vi phạm, hoặc một số lý do khác tôi không thể tái sử dụng các đối tượng kết nối theo cách này?Kết hợp các hành động JPA và JDBC trong một giao dịch

EntityManager em = _em; //acquired from OpenJPA 
em.getTransaction().begin(); 
Connection conn; 
try { 
    OpenJPAEntityManager oem = (OpenJPAEntityManager) em.getDelegate(); 
    conn = oem.getConnection(); 
    PreparedStatement ps = conn.prepareStatement(myStatement); 
    //initialize parameters in ps 
    ps.executeUpdate(); 
    em.merge(myJpaObject); 
    em.getTransaction().commit(); 
} finally { 
    if (ps != null && !ps.isClosed()) { 
     ps.close(); 
    } 
    if (em.getTransaction().isActive()) { 
    em.getTransaction().rollback(); 
    } 
} 

Cảm ơn!

+0

miễn là cả hai đều đang chia sẻ cùng một đối tượng kết nối (mà tôi tin rằng bạn thực hiện bằng cách xem mã), chúng có thể là một phần của cùng một giao dịch. Tại sao bạn không xác minh điều này bằng cách viết một bài kiểm tra đơn giản thay vì đăng câu hỏi. –

+1

Tôi sẽ chỉnh sửa câu hỏi của mình một cách thích hợp - điều này có vẻ đầy đủ chức năng (tôi đã thử nghiệm nó với một số mã thực tế và nó có vẻ hoạt động chính xác). Tôi mới sử dụng JPA/JDBC/cơ sở dữ liệu nói chung, và mối quan tâm của tôi là có một số vấn đề tinh tế mà tôi không biết điều đó không hiển thị trong các trường hợp thử nghiệm đơn giản của tôi. – Sbodd

Trả lời

3

Với một tinh chỉnh, tôi nghĩ điều đó sẽ ổn.

Nó đáng chú ý what the OpenJPA documentation has to say about it:

Kết nối trở lại chỉ đảm bảo được transactionally phù hợp với hoạt động EntityManager khác nếu EntityManager là trong một giao dịch được quản lý hoặc không lạc quan, nếu EntityManager đã đỏ ửng trong dòng điện giao dịch, hoặc nếu bạn đã sử dụng phương thức OpenJPAEntityManager.beginStore để đảm bảo rằng một giao dịch datastore đang được tiến hành. Luôn đóng kết nối trả về trước khi thử bất kỳ hoạt động EntityManager nào khác. OpenJPA sẽ đảm bảo rằng kết nối gốc bên dưới không được giải phóng nếu một giao dịch kho dữ liệu đang được tiến hành.

Giao dịch của bạn không được quản lý, nhưng tôi nghĩ là không lạc quan. Ngoài ra, bạn đã không thực hiện bất kỳ công việc JPA nào giữa việc bắt đầu giao dịch và thực hiện các công cụ JDBC, vì vậy tôi nghĩ bạn có thể rơi vào trường hợp "nếu EntityManager đã bị xóa trong giao dịch hiện tại".

Điều bạn không làm là đóng kết nối trước khi tiếp tục với JPA. Tôi giả định rằng OpenJPA không trả lại kết nối thực tế mà nó đang sử dụng, nhưng một số trình bao bọc quanh nó nên được đóng lại trước khi hồ sơ OpenJPA hoạt động trở lại.

+0

Cảm ơn bạn; đó chính là loại phản hồi tôi đang tìm kiếm! – Sbodd

Các vấn đề liên quan