Hibernate SessionFactory与EntityManagerFactory

时间:2011-04-12 19:51:24

标签: java hibernate jpa sessionfactory hibernate-entitymanager

我是Hibernate的新手,并且不清楚是否使用SessionFactoryEntityManagerFactory来获取hibernate会话。两者有什么区别?优点&缺点

8 个答案:

答案 0 :(得分:337)

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

SessionFactorySession是特定于休眠的。 EntityManager调用hibernate会话。如果您需要EntityManager中没有的某些特定功能,可以通过调用以下方式获取会话:

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

答案 1 :(得分:31)

SessionFactoryEntityManagerFactory

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

JPA and Hibernate relationship

因此,SessionFactory也是JPA EntityManagerFactory

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

SessionEntityManager

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

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

休眠与JPA引导程序

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

  1. 您可以通过Hibernate本机机制进行引导,并通过BootstrapServiceRegistryBuilder创建一个SessionFactory。如果您使用的是Spring,则通过LocalSessionFactoryBean完成Hibernate引导,如this GitHub example所示。
  2. 或者,您可以通过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展开为休眠状态

此外,如果您通过JPA进行引导,并且已经通过EntityManagerFactory注解注入了@PersistenceUnit

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

您可以使用Sessionfactory方法轻松访问基础unwrap

SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);

JPA EntityManager可以完成相同的操作。如果您通过EntityManager注解注入@PersistenceContext

@PersistenceContext
private EntityManager entityManager;

您可以使用Session方法轻松访问基础unwrap

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

结论

因此,您应该通过JPA进行引导,使用EntityManagerFactoryEntityManager,并且仅当您想访问某些不可用的特定于Hibernate的方法时,才将它们解包到与其关联的Hibernate接口。在JPA中,例如fetching the entity via its natural identifier

答案 2 :(得分:30)

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

例如:

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

答案 3 :(得分:20)

使用EntityManagerFactory方法允许我们使用回调方法注释,如@ PrePersist,@ PostPersist,@ PreUpdate,无需额外配置。

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

可以找到相关的Hibernate文档herehere

Related SOF QuestionSpring Forum discussion

答案 4 :(得分:17)

我比EntityManager更喜欢JPA2 SessionFactory API,因为它感觉更现代。一个简单的例子:

JPA:

@PersistenceContext
EntityManager entityManager;

public List<MyEntity> findSomeApples() {
  return entityManager
     .createQuery("from MyEntity where apples=7", MyEntity.class)
     .getResultList();
}

会话工厂:

@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很容易被模拟。

答案 5 :(得分:2)

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

javax.persistence.EntityManager

而不是

org.hibernate.ejb.HibernateEntityManager

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

答案 6 :(得分:1)

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

答案 7 :(得分:0)

EntityManager interface is similar to sessionFactory in hibernate. EntityManager under javax.persistance package but session and sessionFactory under org.hibernate.Session/sessionFactory package.

Entity manager is JPA specific and session/sessionFactory are hibernate specific.