ฉันใหม่เพื่อ Hibernate และผมไม่แน่ใจว่าจะใช้ Hibernate SessionFactory
หรือ JPA เพื่อสร้างไฮเบอร์เนต EntityManagerFactory
Session
ความแตกต่างระหว่างสองสิ่งนี้คืออะไร? ข้อดีและข้อเสียของการใช้แต่ละข้อคืออะไร
ฉันใหม่เพื่อ Hibernate และผมไม่แน่ใจว่าจะใช้ Hibernate SessionFactory
หรือ JPA เพื่อสร้างไฮเบอร์เนต EntityManagerFactory
Session
ความแตกต่างระหว่างสองสิ่งนี้คืออะไร? ข้อดีและข้อเสียของการใช้แต่ละข้อคืออะไร
คำตอบ:
ชอบEntityManagerFactory
และEntityManager
. พวกเขาถูกกำหนดโดยมาตรฐาน JPA
SessionFactory
และSession
จำศีลเฉพาะ การEntityManager
เรียกใช้เซสชันไฮเบอร์เนตภายใต้ประทุน และหากคุณต้องการคุณสมบัติเฉพาะบางอย่างที่ไม่มีในEntityManager
คุณสามารถรับเซสชันได้โดยโทร:
Session session = entityManager.unwrap(Session.class);
Session
จากEntityManager
นี้เช่นเดียวกับSessionFactory.getCurrentSession()
? ฉันหมายความว่ามันจะเปิดใหม่Session
หากยังไม่ได้สร้าง? มันทำงานอย่างไรในสภาพแวดล้อมแบบมัลติเธรด?
ฉันต้องการเพิ่มเกี่ยวกับเรื่องนี้ว่าคุณยังสามารถได้รับเซสชั่นของ Hibernate โดยการเรียกวิธีการจากgetDelegate()
EntityManager
อดีต:
Session session = (Session) entityManager.getDelegate();
ฉันชอบ JPA2 EntityManager
API มากกว่าSessionFactory
เพราะรู้สึกทันสมัยกว่านี้ ตัวอย่างง่ายๆหนึ่งตัวอย่าง:
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;
}
ฉันคิดว่ามันชัดเจนว่าอันแรกดูสะอาดกว่าและทดสอบง่ายกว่าเพราะ EntityManager สามารถล้อเลียนได้ง่าย
return sessionFactory.getCurrentSession().createQuery("from User where id=1").list()
การใช้วิธีการ EntityManagerFactory ช่วยให้เราสามารถใช้คำอธิบายประกอบวิธีการโทรกลับเช่น @PrePersist, @ PostPersist, @ PreUpdate โดยไม่มีการกำหนดค่าเพิ่มเติม
การใช้การเรียกกลับที่คล้ายกันขณะใช้ SessionFactory จะต้องใช้ความพยายามเป็นพิเศษ
เอกสาร Hibernate ที่เกี่ยวข้องสามารถดูได้ที่นี่และที่นี่
SessionFactory
เมื่อเทียบกับ EntityManagerFactory
ดังที่ฉันได้อธิบายไว้ในคู่มือผู้ใช้ไฮเบอร์เนตไฮเบอร์เนตจะSessionFactory
ขยาย JPA EntityManagerFactory
ดังที่แสดงในแผนภาพต่อไปนี้:
ดังนั้นSessionFactory
ยังเป็น EntityManagerFactory
JPA
ทั้งสองSessionFactory
และEntityManagerFactory
ประกอบด้วยข้อมูลเมตาทำแผนที่นิติบุคคลและช่วยให้คุณสามารถสร้าง Hibernate หรือSession
EntityManager
Session
เมื่อเทียบกับ EntityManager
เช่นเดียวกับSessionFactory
และEntityManagerFactory
การ Hibernate Session
ขยาย EntityManager
JPA ดังนั้นวิธีการทั้งหมดที่กำหนดโดยที่EntityManager
มีอยู่ในไฮเบอร์เนตSession
มีอยู่ในไฮเบอร์เนต
Session
และ `EntityManager แปลเปลี่ยนสถานะนิติบุคคลลงในคำสั่ง SQL เช่น SELECT, INSERT, UPDATE และลบ
เมื่อทำการบู๊ตแอปพลิเคชั่น JPA หรือไฮเบอร์เนตคุณมีสองทางเลือก:
SessionFactory
BootstrapServiceRegistryBuilder
หากคุณใช้ Spring การบูตไฮเบอร์เนตจะทำผ่านทางLocalSessionFactoryBean
ดังที่แสดงในตัวอย่าง GitHubนี้EntityManagerFactory
ผ่านชั้นหรือPersistence
EntityManagerFactoryBuilder
หากคุณใช้งาน Spring บูตของ JPA จะทำผ่านทางLocalContainerEntityManagerFactoryBean
ดังที่แสดงในตัวอย่าง GitHubนี้ต้องการการบู๊ตผ่าน JPA นั่นเป็นเพราะ JPA FlushModeType.AUTO
เป็นทางเลือกที่ดีกว่าเดิมFlushMode.AUTO
ซึ่งแบ่งอ่านของคุณเขียนความสอดคล้องสำหรับแบบสอบถาม SQL พื้นเมือง
นอกจากนี้หากคุณบูตบู๊ตผ่าน JPA และคุณฉีดEntityManagerFactory
ผ่าน@PersistenceUnit
หมายเหตุประกอบ:
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
คุณสามารถเข้าถึงต้นแบบSessionfactory
โดยใช้unwrap
วิธีการ:
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
เดียวกันสามารถทำได้ด้วย EntityManager
JPA หากคุณฉีดEntityManager
ผ่าน@PersistenceContext
หมายเหตุประกอบ:
@PersistenceContext
private EntityManager entityManager;
คุณสามารถเข้าถึงต้นแบบSession
โดยใช้unwrap
วิธีการ:
Session session = entityManager.unwrap(Session.class);
ดังนั้นคุณควรบูตผ่าน JPA ใช้EntityManagerFactory
และEntityManager
และมีเพียงแกะเหล่านั้นไปยังเฟซ Hibernate เกี่ยวข้องของพวกเขาเมื่อคุณต้องการที่จะได้รับการเข้าถึงบางวิธี Hibernate เฉพาะที่ไม่สามารถใช้ได้ใน JPA เช่นการเรียกนิติบุคคลผ่านตัวระบุตามธรรมชาติของมัน
โดยใช้ EntityManager รหัสจะไม่คู่กับโหมดไฮเบอร์เนตอย่างแน่นหนาอีกต่อไป แต่สำหรับสิ่งนี้ในการใช้งานเราควรใช้:
javax.persistence.EntityManager
แทน
org.hibernate.ejb.HibernateEntityManager
ในทำนองเดียวกันสำหรับ EntityManagerFactory ให้ใช้อินเตอร์เฟส javax ด้วยวิธีนี้รหัสจะถูกรวมเข้าด้วยกันอย่างหลวม ๆ หากมีการใช้ JPA 2 ที่ดีกว่าการจำศีลการสลับจะเป็นเรื่องง่าย ในกรณีที่รุนแรงเราสามารถพิมพ์ cast ไปที่ HibernateEntityManager
EntityManagerFactory เป็นการใช้งานมาตรฐานมันเหมือนกันในทุกการใช้งาน หากคุณย้าย ORM ของคุณสำหรับผู้ให้บริการรายอื่นเช่น EclipseLink จะไม่มีการเปลี่ยนแปลงใด ๆ ในวิธีการจัดการธุรกรรม ในทางตรงกันข้ามหากคุณใช้โรงงานเซสชันของไฮเบอร์เนตจะเชื่อมโยงกับ API ไฮเบอร์เนตและไม่สามารถย้ายไปยังผู้จัดจำหน่ายรายใหม่ได้
อินเทอร์เฟซ EntityManager คล้ายกับ sessionFactory ในโหมดไฮเบอร์เนต EntityManager ภายใต้แพ็คเกจ javax.persistance แต่เซสชันและ sessionFactory ภายใต้ org.hibernate.Session / sessionFactory แพ็คเกจ
ผู้จัดการเอนทิตีเป็น JPA เฉพาะและเซสชั่น / sessionFactory เป็นไฮเบอร์เนตเฉพาะ