SessionFactory 与 EntityManagerFactory
正如我在Hibernate User Guide 中解释的那样,Hibernate SessionFactory 扩展了 JPA EntityManagerFactory,如下图所示:
所以,SessionFactory 也是 JPA EntityManagerFactory。
SessionFactory 和 EntityManagerFactory 都包含实体映射元数据,并允许您创建 Hibernate Session 或 EntityManager。
Session 与 EntityManager
就像SessionFactory 和EntityManagerFactory 一样,Hibernate Session 扩展了 JPA EntityManager。所以,EntityManager 定义的所有方法都可以在 Hibernate Session 中使用。
Session 和 `EntityManager 将 entity state transitions 转换为 SQL 语句,例如 SELECT、INSERT、UPDATE 和 DELETE。
Hibernate 与 JPA 引导程序
在引导 JPA 或 Hibernate 应用程序时,您有两种选择:
- 您可以通过 Hibernate 原生机制进行引导,并通过
BootstrapServiceRegistryBuilder 创建一个 SessionFactory。如果您使用的是 Spring,Hibernate 引导是通过 LocalSessionFactoryBean 完成的,如 this GitHub example 所示。
- 或者,您可以通过
Persistence 类或EntityManagerFactoryBuilder 创建一个JPA EntityManagerFactory。如果您使用 Spring,JPA 引导是通过 LocalContainerEntityManagerFactoryBean 完成的,如 this GitHub example 所示。
首选通过 JPA 引导。这是因为 JPA FlushModeType.AUTO 比旧版 FlushMode.AUTO 更好的选择,旧版 breaks read-your-writes consistency for native SQL queries。
将 JPA 解包到 Hibernate
另外,如果您通过 JPA 引导,并且您已经通过 @PersistenceUnit 注释注入了 EntityManagerFactory:
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
您可以使用unwrap 方法轻松访问底层Sessionfactory:
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
JPA EntityManager 也可以做到这一点。如果你通过@PersistenceContext注解注入EntityManager:
@PersistenceContext
private EntityManager entityManager;
您可以使用unwrap 方法轻松访问底层Session:
Session session = entityManager.unwrap(Session.class);
结论
因此,您应该通过 JPA 引导,使用 EntityManagerFactory 和 EntityManager,并且仅当您想要访问 JPA 中不可用的某些特定于 Hibernate 的方法时,才将它们解包到它们关联的 Hibernate 接口,例如通过其natural identifier 获取实体。