Trong Bean Session Stateless, EntityManager
được tiêm nhưng tôi muốn giữ đối tượng Connection
để gọi thủ tục DB. Có giải pháp nào cho vấn đề này không?Lấy một đối tượng kết nối JDBC từ một Stateless Bean
Trả lời
Đâ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.
unwrap (java.sql.Connection.class) cũng không hoạt động trong OpenJPA (ít nhất 2.1.1) –
@Pawel, nó có vẻ là ["cố định" trong 2.2.0] (https: //issues.apache .org/jira/duyệt/OPENJPA-1803). –
Cảm ơn bạn! nhưng họ chưa phát hành 2.2.0 chưa :) –
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.
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()
.
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();
}
}
}
});
}
bạn nên bỏ nó vào "org.hibernate.Session" và không "org.hsqldb.Session" – dulon
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
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;
}
}
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);
}
}
- 1. Cách lấy tài nguyên kết nối từ đối tượng PDO?
- 2. Cách lấy giá trị của các tham số liên kết từ đối tượng Oracle JDBC PreparedStatement
- 3. JDBC- postgres, kết nối từ chối
- 4. Kết nối JDBC treo
- 5. C# Lấy đối tượng DbConnection đúng bằng chuỗi kết nối
- 6. Cách lấy đối tượng Connection hiện tại trong Spring JDBC
- 7. Kết nối JDBC an toàn
- 8. Kết nối JDBC trong Android
- 9. theo dõi kết nối JDBC
- 10. Hồ bơi kết nối JDBC Tomcat (phát hành kết nối)
- 11. Lỗi "Tham chiếu đối tượng không được đặt thành một đối tượng của một đối tượng" kết nối với máy chủ SOAP từ PHP
- 12. JDBC URL kết nối Đối với Embedded Derby trong một webapp
- 13. Thực hành tốt: Kết nối JDBC
- 14. Thiếu kết nối trong hồ bơi kết nối jdbc tomcat
- 15. PHP: lấy một khóa duy nhất từ đối tượng
- 16. Lấy tên đối tượng từ bên trong một hàm
- 17. lấy một đối tượng từ tăng :: tùy chọn
- 18. Cách nhận kết nối jdbc từ phiên ngủ đông?
- 19. Trích xuất các đối tượng đã kết nối từ một hình ảnh trong Python
- 20. Tomcat và kết nối JDBC pooling
- 21. Nối tiếp Kafka của một đối tượng
- 22. Python 3 - Kết nối với JDBC
- 23. Constructor lấy đối số - Xác định đối tượng thông thường hoặc bean mùa xuân?
- 24. Nối tiếp một đối tượng vào JSON
- 25. Java JDBC tình trạng kết nối
- 26. Cách lấy thuộc tính đối tượng từ mỗi đối tượng trong một mảng?
- 27. Lỗi khi kết nối bằng JDBC Mysql
- 28. Sự khác biệt giữa đối tượng con trỏ và đối tượng kết nối
- 29. Git: lấy một đối tượng cụ thể từ một từ xa
- 30. Kết nối JDBC- Class.forName vs Class.forName(). NewInstance?
Các JPA API không cho phép một điều như vậy, mặc dù API JDO làm. – DataNucleus