Saya baru mengenal Hibernate dan saya tidak yakin apakah akan menggunakan Hibernate SessionFactoryatau JPA EntityManagerFactoryuntuk membuat Hibernate Session.
Apa perbedaan antara keduanya? Apa pro & kontra menggunakan masing-masing?
Saya baru mengenal Hibernate dan saya tidak yakin apakah akan menggunakan Hibernate SessionFactoryatau JPA EntityManagerFactoryuntuk membuat Hibernate Session.
Apa perbedaan antara keduanya? Apa pro & kontra menggunakan masing-masing?
Jawaban:
Lebih suka EntityManagerFactorydan EntityManager. Mereka didefinisikan oleh standar JPA.
SessionFactorydan Sessionkhusus untuk hibernasi. The EntityManagermemanggil sesi hibernasi di bawah tenda. Dan jika Anda memerlukan beberapa fitur spesifik yang tidak tersedia di EntityManager, Anda dapat memperoleh sesi dengan menelepon:
Session session = entityManager.unwrap(Session.class);
Sessiondari EntityManager, sama dengan SessionFactory.getCurrentSession()? Maksud saya, apakah itu akan terbuka baru Sessionjika belum dibuat? Bagaimana cara kerjanya di lingkungan multithreaded?
Saya ingin menambahkan ini bahwa Anda juga bisa mendapatkan sesi Hibernate dengan memanggil getDelegate()metode dari EntityManager.
ex:
Session session = (Session) entityManager.getDelegate();
Saya lebih suka JPA2 EntityManagerAPI daripada SessionFactory, karena rasanya lebih modern. Satu contoh sederhana:
JPA:
@PersistenceContext
EntityManager entityManager;
public List<MyEntity> findSomeApples() {
return entityManager
.createQuery("from MyEntity where apples=7", MyEntity.class)
.getResultList();
}
SessionFactory:
@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;
}
Saya pikir sudah jelas bahwa yang pertama terlihat lebih bersih dan juga lebih mudah untuk diuji karena EntityManager dapat dengan mudah diejek.
return sessionFactory.getCurrentSession().createQuery("from User where id=1").list()
Menggunakan pendekatan EntityManagerFactory memungkinkan kita untuk menggunakan anotasi metode panggilan balik seperti @PrePersist, @ PostPersist, @ PreUpdate tanpa konfigurasi tambahan.
Menggunakan panggilan balik yang serupa saat menggunakan SessionFactory akan membutuhkan upaya ekstra.
Dokumen hibernasi terkait dapat ditemukan di sini dan di sini .
SessionFactory vs. EntityManagerFactorySeperti yang saya jelaskan dalam Panduan Pengguna Hibernate , Hibernate SessionFactorymemperluas JPA EntityManagerFactory, seperti yang diilustrasikan oleh diagram berikut:
Jadi, SessionFactoryini juga merupakan JPA EntityManagerFactory.
Baik SessionFactorydan EntityManagerFactorymetadata pemetaan entitas dan memungkinkan Anda untuk membuat Hibernate Sessionatau EntityManager.
Session vs. EntityManagerSama seperti SessionFactorydan EntityManagerFactory, Hibernate Sessionmemperluas JPA EntityManager. Jadi, semua metode yang ditentukan oleh EntityManagertersedia di HibernateSession .
The Sessiondan `EntityManager menerjemahkan transisi status entitas ke dalam pernyataan SQL, seperti SELECT, INSERT, UPDATE, dan DELETE.
Saat mem-bootstrap aplikasi JPA atau Hibernate, Anda memiliki dua pilihan:
SessionFactoryvia BootstrapServiceRegistryBuilder. Jika Anda menggunakan Spring, bootstrap Hibernate dilakukan melalui LocalSessionFactoryBean, seperti yang diilustrasikan oleh contoh GitHub ini .EntityManagerFactorymelalui Persistencekelas atau EntityManagerFactoryBuilder. Jika Anda menggunakan Spring, bootstrap JPA dilakukan melalui LocalContainerEntityManagerFactoryBean, seperti yang diilustrasikan oleh contoh GitHub ini .Bootstrap melalui JPA lebih disukai. Itu karena JPA FlushModeType.AUTOadalah pilihan yang jauh lebih baik daripada warisan FlushMode.AUTO, yang memecah konsistensi baca-Anda-tulis untuk kueri SQL asli .
Juga, jika Anda bootstrap melalui JPA, dan Anda telah menyuntikkan EntityManagerFactorymelalui @PersistenceUnitanotasi:
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
Anda dapat dengan mudah mendapatkan akses ke dasar Sessionfactorymenggunakan unwrapmetode:
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
Hal yang sama dapat dilakukan dengan JPA EntityManager. Jika Anda menyuntikkan EntityManagermelalui @PersistenceContextanotasi:
@PersistenceContext
private EntityManager entityManager;
Anda dapat dengan mudah mendapatkan akses ke dasar Sessionmenggunakan unwrapmetode:
Session session = entityManager.unwrap(Session.class);
Jadi, Anda harus mem-bootstrap melalui JPA, menggunakan EntityManagerFactorydan EntityManager, dan hanya membuka mereka ke antarmuka Hibernate terkait ketika Anda ingin mendapatkan akses ke beberapa metode khusus Hibernate yang tidak tersedia di JPA, seperti mengambil entitas melalui pengidentifikasi alami .
Dengan menggunakan EntityManager, kode tidak lagi dipasangkan dengan hibernate. Namun untuk ini, dalam penggunaannya kita harus menggunakan:
javax.persistence.EntityManager
dari pada
org.hibernate.ejb.HibernateEntityManager
Demikian pula, untuk EntityManagerFactory, gunakan antarmuka javax. Dengan begitu, kodenya secara longgar digabungkan. Jika ada implementasi JPA 2 yang lebih baik daripada hibernate, beralih akan mudah. Dalam kasus ekstrim, kita bisa mengetikkan cast ke HibernateEntityManager.
EntityManagerFactory adalah implementasi standar, itu sama di semua implementasi. Jika Anda memigrasikan ORM Anda ke penyedia lain seperti EclipseLink, tidak akan ada perubahan dalam pendekatan untuk menangani transaksi. Sebaliknya, jika Anda menggunakan pabrik sesi hibernate, itu terkait dengan API hibernasi dan tidak dapat bermigrasi ke vendor baru.
Antarmuka EntityManager mirip dengan sessionFactory di hibernasi. EntityManager di bawah paket javax.persistance tetapi sesi dan sessionFactory di bawah paket org.hibernate.Session / sessionFactory.
Manajer entitas adalah spesifik JPA dan session / sessionFactory spesifik untuk hibernasi.