Hibernate SessionFactory与JPA EntityManagerFactory

问题描述 投票:250回答:8

我是Hibernate的新手,我不确定是否要使用Hibernate SessionFactory或JPA EntityManagerFactory创建Hibernate Session

这两者之间有什么区别?使用这些功能的利弊是什么?

java hibernate jpa sessionfactory hibernate-entitymanager
8个回答
364
投票

优选EntityManagerFactoryEntityManager。它们由JPA标准定义。

SessionFactorySession是休眠特定的。 EntityManager在后台调用休眠会话。并且,如果您需要EntityManager中不可用的某些特定功能,则可以通过以下方式获取会话:

Session session = entityManager.unwrap(Session.class);

32
投票

我想补充一点,您也可以通过从getDelegate()调用EntityManager方法来获得Hibernate的会话。

ex:

Session session = (Session) entityManager.getDelegate();

22
投票

我更喜欢JPA2EntityManagerAPI,而不是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可以轻松模拟。


21
投票

使用EntityManagerFactory方法使我们无需额外配置即可使用@ PrePersist,@ PostPersist,@ PreUpdate之类的回调方法注释。

使用SessionFactory时使用类似的回调将需要额外的精力。

可以在herehere中找到相关的Hibernate文档。

[Related SOF QuestionSpring Forum discussion


21
投票

[SessionFactory vs. EntityManagerFactory] >>

正如我在Hibernate User Guide中所解释的,Hibernate SessionFactory扩展了JPA EntityManagerFactory,如下图所示:

JPA and Hibernate relationship

因此,SessionFactory也是JPA EntityManagerFactory

SessionFactoryEntityManagerFactory都包含实体映射元数据,并允许您创建休眠SessionEntityManager

[Session vs. EntityManager] >>

就像SessionFactoryEntityManagerFactory一样,休眠Session扩展了JPA EntityManager。因此,EntityManager定义的所有方法都可以在Hibernate Session中使用。

Session和`EntityManager将entity state transitions转换为SQL语句,例如SELECT,INSERT,UPDATE和DELETE。

Hibernate vs. JPA引导程序

引导JPA或Hibernate应用程序时,有两种选择:

  1. 您可以通过Hibernate本机机制进行引导,并通过SessionFactory创建一个BootstrapServiceRegistryBuilder。如果您使用的是Spring,则通过BootstrapServiceRegistryBuilder完成Hibernate引导,如LocalSessionFactoryBean所示。
  2. 或者,您可以通过this GitHub example类或EntityManagerFactory创建JPA Persistence。如果您使用的是Spring,则JPA引导程序将通过Persistence完成,如EntityManagerFactoryBuilder所示。
  3. 首选通过JPA引导。这是因为JPA EntityManagerFactoryBuilder比传统的LocalContainerEntityManagerFactoryBean this GitHub example更好。

    将JPA展开为休眠状态

    此外,如果您通过JPA进行引导,并且已经通过FlushModeType.AUTO注释注入了FlushMode.AUTO

breaks read-your-writes consistency for native SQL queries

您可以使用EntityManagerFactory方法轻松访问基础@PersistenceUnit

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

JPA Sessionfactory可以执行相同的操作。如果通过unwrap注释注入SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);

EntityManager

您可以使用EntityManager方法轻松访问基础@PersistenceContext

@PersistenceContext
private EntityManager entityManager;

结论

因此,您应该通过JPA进行引导,使用Sessionunwrap,并且仅当您想访问JPA中不可用的某些特定于Hibernate的方法时才将它们解包到其关联的Hibernate接口,例如[ C0]。

通过使用EntityManager,代码不再与休眠紧密结合。但是为此,在使用中我们应该使用:

Session session = entityManager.unwrap(Session.class);

而不是

EntityManagerFactory

类似地,对于EntityManagerFactory,请使用javax接口。这样,代码就可以松散耦合。如果有一个比休眠更好的JPA 2实现,则切换将很容易。在极端情况下,我们可以将强制类型转换为HibernateEntityManager。

EntityManagerFactory是标准实现,在所有实现中都相同。如果您将ORM迁移到其他任何提供程序(例如EclipseLink),则处理事务的方法将没有任何变化。相反,如果使用hibernate的会话工厂,则它将与hibernate API绑定在一起,并且无法迁移到新的供应商。

EntityManager接口类似于休眠中的sessionFactory。EntityManager在javax.persistance包下,而session和sessionFactory在org.hibernate.Session / sessionFactory包下。

实体管理器是JPA特定的,而session / sessionFactory是休眠的。


2
投票

通过使用EntityManager,代码不再与休眠紧密结合。但是为此,在使用中我们应该使用:

Session session = entityManager.unwrap(Session.class);

2
投票

EntityManagerFactory是标准实现,在所有实现中都相同。如果您将ORM迁移到其他任何提供程序(例如EclipseLink),则处理事务的方法将没有任何变化。相反,如果使用hibernate的会话工厂,则它将与hibernate API绑定在一起,并且无法迁移到新的供应商。


1
投票

EntityManager接口类似于休眠中的sessionFactory。EntityManager在javax.persistance包下,而session和sessionFactory在org.hibernate.Session / sessionFactory包下。

实体管理器是JPA特定的,而session / sessionFactory是休眠的。

© www.soinside.com 2019 - 2024. All rights reserved.