ฉันใหม่เพื่อ Hibernate และผมไม่แน่ใจว่าจะใช้ Hibernate SessionFactoryหรือ JPA เพื่อสร้างไฮเบอร์เนต EntityManagerFactorySession
ความแตกต่างระหว่างสองสิ่งนี้คืออะไร? ข้อดีและข้อเสียของการใช้แต่ละข้อคืออะไร
ฉันใหม่เพื่อ Hibernate และผมไม่แน่ใจว่าจะใช้ Hibernate SessionFactoryหรือ JPA เพื่อสร้างไฮเบอร์เนต EntityManagerFactorySession
ความแตกต่างระหว่างสองสิ่งนี้คืออะไร? ข้อดีและข้อเสียของการใช้แต่ละข้อคืออะไร
คำตอบ:
ชอบ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 EntityManagerAPI มากกว่า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ยังเป็น EntityManagerFactoryJPA
ทั้งสองSessionFactoryและEntityManagerFactoryประกอบด้วยข้อมูลเมตาทำแผนที่นิติบุคคลและช่วยให้คุณสามารถสร้าง Hibernate หรือSessionEntityManager
Session เมื่อเทียบกับ EntityManagerเช่นเดียวกับSessionFactoryและEntityManagerFactoryการ Hibernate Sessionขยาย EntityManagerJPA ดังนั้นวิธีการทั้งหมดที่กำหนดโดยที่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);
เดียวกันสามารถทำได้ด้วย EntityManagerJPA หากคุณฉีด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 เป็นไฮเบอร์เนตเฉพาะ