Hibernate SessionFactory与EntityManagerFactory

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

优先使用EntityManagerFactoryEntityManager 。 它们由JPA标准定义。

SessionFactorySession是hibernate特定的。 EntityManager在引擎下调用hibernate会话。 如果您需要某些EntityManager中不可用的特定function,则可以通过调用以下命令获取会话:

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

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

例如:

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

使用EntityManagerFactory方法允许我们使用像@PrePersist,@ PostPersist,@ PreUpdate这样的callback方法注释,而不需要额外的configuration。

在使用SessionFactory时使用类似的callback将需要额外的努力。

相关的Hibernate文档可以在这里和这里find。

相关的SOF问题和春季论坛讨论

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

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; } 

我认为很明显,第一个看起来更清洁,也更容易testing,因为EntityManager可以轻松地嘲笑。

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

 javax.persistence.EntityManager 

代替

 org.hibernate.ejb.HibernateEntityManager 

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