Tôi chưa quen với Hibernate và tôi không chắc nên sử dụng Hibernate SessionFactoryhay JPA EntityManagerFactoryđể tạo Hibernate Session.
sự khác biệt giữa hai cái đó là gì? Những ưu và nhược điểm của việc sử dụng mỗi trong số đó là gì?
Tôi chưa quen với Hibernate và tôi không chắc nên sử dụng Hibernate SessionFactoryhay JPA EntityManagerFactoryđể tạo Hibernate Session.
sự khác biệt giữa hai cái đó là gì? Những ưu và nhược điểm của việc sử dụng mỗi trong số đó là gì?
Câu trả lời:
Thích EntityManagerFactoryvà EntityManager. Chúng được xác định theo tiêu chuẩn JPA.
SessionFactoryvà Sessionđặc biệt ngủ đông. Việc EntityManagergọi phiên ngủ đông dưới mui xe. Và nếu bạn cần một số tính năng cụ thể không có sẵn trong EntityManager, bạn có thể có được phiên bằng cách gọi:
Session session = entityManager.unwrap(Session.class);
Sessiontừ EntityManager, giống như SessionFactory.getCurrentSession()? Ý tôi là, nó sẽ mở mới Sessionnếu nó chưa được tạo? Làm thế nào nó hoạt động trong môi trường đa luồng?
Tôi muốn thêm vào điều này để bạn cũng có thể có được phiên của Hibernate bằng cách gọi getDelegate()phương thức từ EntityManager.
Ví dụ:
Session session = (Session) entityManager.getDelegate();
Tôi thích EntityManagerAPI JPA2 hơn SessionFactory, vì nó cảm thấy hiện đại hơn. Một ví dụ đơn giản:
JPA:
@PersistenceContext
EntityManager entityManager;
public List<MyEntity> findSomeApples() {
return entityManager
.createQuery("from MyEntity where apples=7", MyEntity.class)
.getResultList();
}
Phiên họp:
@Autowired
SessionFactory sessionFactory;
public List<MyEntity> findSomeApples() {
Session session = sessionFactory.getCurrentSession();
List<?> result = session.createQuery("from MyEntity where apples=7")
.list();
@SuppressWarnings("unchecked")
List<MyEntity> resultCasted = (List<MyEntity>) result;
return resultCasted;
}
Tôi nghĩ rõ ràng rằng cái đầu tiên trông sạch hơn và cũng dễ kiểm tra hơn vì EntityManager có thể dễ dàng bị chế giễu.
return sessionFactory.getCurrentSession().createQuery("from User where id=1").list()
Sử dụng phương pháp EntityManagerFactory cho phép chúng tôi sử dụng các chú thích phương thức gọi lại như @PrePersist, @ PostPersist, @ PreUpdate mà không cần cấu hình thêm.
Sử dụng các cuộc gọi lại tương tự trong khi sử dụng SessionFactory sẽ đòi hỏi thêm nỗ lực.
Tài liệu Hibernate liên quan có thể được tìm thấy ở đây và đây .
SessionFactory so với EntityManagerFactoryNhư tôi đã giải thích trong Hướng dẫn sử dụng Hibernate , Hibernate SessionFactorymở rộng JPA EntityManagerFactory, như được minh họa bằng sơ đồ sau:
Vì vậy, SessionFactorycũng là một JPA EntityManagerFactory.
Cả SessionFactoryvà EntityManagerFactorychứa siêu dữ liệu ánh xạ thực thể và cho phép bạn tạo Hibernate Sessionhoặc a EntityManager.
Session so với EntityManagerCũng giống như SessionFactoryvà EntityManagerFactory, Hibernate Sessionmở rộng JPA EntityManager. Vì vậy, tất cả các phương thức được xác định bởi EntityManagercó sẵn trong Hibernate Session.
Và Session`EntityManager dịch chuyển trạng thái thực thể thành các câu lệnh SQL, như CHỌN, CHERTN, CẬP NHẬT và XÓA.
Khi bootstrapping ứng dụng JPA hoặc Hibernate, bạn có hai lựa chọn:
SessionFactorythông qua BootstrapServiceRegistryBuilder. Nếu bạn đang sử dụng Spring, bootstrap Hibernate được thực hiện thông qua LocalSessionFactoryBean, như được minh họa bằng ví dụ GitHub này .EntityManagerFactorythông qua Persistencelớp hoặc EntityManagerFactoryBuilder. Nếu bạn đang sử dụng Spring, bootstrap JPA được thực hiện thông qua LocalContainerEntityManagerFactoryBean, như được minh họa bằng ví dụ GitHub này .Bootstrapping thông qua JPA sẽ được ưu tiên. Đó là bởi vì JPA FlushModeType.AUTOlà một lựa chọn tốt hơn nhiều so với di sản FlushMode.AUTO, phá vỡ tính nhất quán đọc-ghi của bạn cho các truy vấn SQL gốc .
Ngoài ra, nếu bạn bootstrap thông qua JPA và bạn đã tiêm EntityManagerFactorythông qua @PersistenceUnitchú thích:
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
Bạn có thể dễ dàng truy cập vào bên dưới Sessionfactorybằng unwrapphương thức:
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
Điều tương tự có thể được thực hiện với JPA EntityManager. Nếu bạn tiêm EntityManagerthông qua @PersistenceContextchú thích:
@PersistenceContext
private EntityManager entityManager;
Bạn có thể dễ dàng truy cập vào bên dưới Sessionbằng unwrapphương thức:
Session session = entityManager.unwrap(Session.class);
Vì vậy, bạn nên bootstrap thông qua JPA, sử dụng EntityManagerFactoryvà EntityManagervà chỉ hủy kết nối chúng với các giao diện Hibernate liên quan của chúng khi bạn muốn truy cập vào một số phương thức dành riêng cho Hibernate không có sẵn trong JPA, như tìm nạp thực thể thông qua định danh tự nhiên .
Bằng cách sử dụng EntityManager, mã không còn được kết hợp chặt chẽ với chế độ ngủ đông. Nhưng đối với điều này, trong sử dụng chúng ta nên sử dụng:
javax.persistence.EntityManager
thay vì
org.hibernate.ejb.HibernateEntityManager
Tương tự, đối với EntityManagerFactory, hãy sử dụng giao diện javax. Bằng cách đó, mã được ghép lỏng lẻo. Nếu có triển khai JPA 2 tốt hơn ngủ đông, việc chuyển đổi sẽ dễ dàng. Trong trường hợp cực đoan, chúng ta có thể nhập cast vào HibernateEntityManager.
EntityManagerFactory là triển khai tiêu chuẩn, nó giống nhau trên tất cả các triển khai. Nếu bạn di chuyển ORM của mình cho bất kỳ nhà cung cấp nào khác như EclipseLink, sẽ không có bất kỳ thay đổi nào trong cách tiếp cận để xử lý giao dịch. Ngược lại, nếu bạn sử dụng nhà máy phiên của hibernate, nó được gắn với API ngủ đông và không thể di chuyển sang nhà cung cấp mới.
Giao diện EntityManager tương tự như sessionFactory trong chế độ ngủ đông. EntityManager trong gói javax.persistance nhưng phiên và sessionFactory trong gói org.hibernate.Session / sessionFactory.
Trình quản lý thực thể là JPA cụ thể và session / sessionFactory là chế độ ngủ đông cụ thể.