Hibernate SessionFactory 与 JPA EntityManagerFactory

发布于 2024-10-31 20:49:11 字数 182 浏览 0 评论 0 原文

我是 Hibernate 新手,不确定是使用 Hibernate SessionFactory 还是 JPA EntityManagerFactory 来创建 Hibernate Session

这两者有什么区别?有什么优点和优点?使用其中每一个的缺点?

I am new to Hibernate and I'm not sure whether to use a Hibernate SessionFactory or a JPA EntityManagerFactory to create a Hibernate Session.

What is the difference between these two? What are the pros & cons of using each of those?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

奈何桥上唱咆哮 2024-11-07 20:49:11

首选 EntityManagerFactory 和 EntityManager。它们由 JPA 标准定义。

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

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

Prefer EntityManagerFactory and EntityManager. They are defined by the JPA standard.

SessionFactory and Session are hibernate-specific. The EntityManager invokes the hibernate session under the hood. And if you need some specific features that are not available in the EntityManager, you can obtain the session by calling:

Session session = entityManager.unwrap(Session.class);
玩世 2024-11-07 20:49:11

SessionFactoryEntityManagerFactory

正如我在 Hibernate 用户指南,Hibernate SessionFactory 扩展了 JPA EntityManagerFactory,如下图所示:

JPA 和 Hibernate 关系

因此,SessionFactory 也是一个 JPA EntityManagerFactory

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

SessionEntityManager

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

Session 和 `EntityManager 翻译 实体状态转换为 SQL 语句,例如 SELECT、INSERT、UPDATE 和 DELETE。

Hibernate 与 JPA 引导

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

  1. 您可以通过 Hibernate 本机机制引导,并通过 SessionFactory .com/vladmihalcea/high-performance-java-persistence/blob/master/core/src/test/java/com/vladmihalcea/book/hpjp/util/AbstractTest.java#L147" rel="noreferrer"><代码> BootstrapServiceRegistryBuilder。如果您使用 Spring,则 Hibernate 引导程序是通过 LocalSessionFactoryBean 完成的,如 此 GitHub 示例
  2. 或者,您可以通过 Persistence 类或 EntityManagerFactoryBuilder。如果您使用 Spring,则 JPA 引导是通过 LocalContainerEntityManagerFactoryBean 完成的,如 此 GitHub 示例

通过 JPA 引导是首选。这是因为 JPA FlushModeType.AUTO 是比旧版 FlushMode.AUTO 更好的选择,后者破坏本机 SQL 查询的读写一致性

将 JPA 解包到 Hibernate

另外,如果您通过 JPA 引导,并且已通过 @PersistenceUnit 注释注入了 EntityManagerFactory:

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

您可以轻松访问底层 Sessionfactory 使用 unwrap 方法:

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,并且仅当您想要访问某些 Hibernate 时才将它们解包到其关联的 Hibernate 接口- JPA 中不可用的特定方法,例如通过其 自然标识符

SessionFactory vs. EntityManagerFactory

As I explained in the Hibernate User Guide, the Hibernate SessionFactory extends the JPA EntityManagerFactory, as illustrated by the following diagram:

JPA and Hibernate relationship

So, the SessionFactory is also a JPA EntityManagerFactory.

Both the SessionFactory and the EntityManagerFactory contain the entity mapping metadata and allow you to create a Hibernate Session or a EntityManager.

Session vs. EntityManager

Just like the SessionFactory and EntityManagerFactory, the Hibernate Session extends the JPA EntityManager. So, all methods defined by the EntityManager are available in the Hibernate Session.

The Session and the `EntityManager translate entity state transitions into SQL statements, like SELECT, INSERT, UPDATE, and DELETE.

Hibernate vs. JPA bootstrap

When bootstrapping a JPA or Hibernate application, you have two choices:

  1. You can bootstrap via the Hibernate native mechanism, and create a SessionFactory via the BootstrapServiceRegistryBuilder. If you're using Spring, the Hibernate bootstrap is done via the LocalSessionFactoryBean, as illustrated by this GitHub example.
  2. Or, you can create a JPA EntityManagerFactory via the Persistence class or the EntityManagerFactoryBuilder. If you're using Spring, the JPA bootstrap is done via the LocalContainerEntityManagerFactoryBean, as illustrated by this GitHub example.

Bootstrapping via JPA is to be preferred. That's because the JPA FlushModeType.AUTO is a much better choice than the legacy FlushMode.AUTO, which breaks read-your-writes consistency for native SQL queries.

Unwrapping JPA to Hibernate

Also, if you bootstrap via JPA, and you have injected the EntityManagerFactory via the @PersistenceUnit annotation:

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

You can easily get access to the underlying Sessionfactory using the unwrap method:

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

The same can be done with the JPA EntityManager. If you inject the EntityManager via the @PersistenceContext annotation:

@PersistenceContext
private EntityManager entityManager;

You can easily get access to the underlying Session using the unwrap method:

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

Conclusion

So, you should bootstrap via JPA, use the EntityManagerFactory and EntityManager, and only unwrap those to their associated Hibernate interfaces when you want to get access to some Hibernate-specific methods that are not available in JPA, like fetching the entity via its natural identifier.

傲娇萝莉攻 2024-11-07 20:49:11

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

前任:

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

I want to add on this that you can also get Hibernate's session by calling getDelegate() method from EntityManager.

ex:

Session session = (Session) entityManager.getDelegate();
茶底世界 2024-11-07 20:49:11

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

我认为很明显,第一个看起来更干净,也更容易测试,因为 EntityManager 可以很容易地被模拟。

I prefer the JPA2 EntityManager API over SessionFactory, because it feels more modern. One simple example:

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

I think it's clear that the first one looks cleaner and is also easier to test because EntityManager can be easily mocked.

故事↓在人 2024-11-07 20:49:11

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

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

相关 Hibernate 文档可以在此处 和 这里

相关 SOF 问题Spring 论坛讨论

Using EntityManagerFactory approach allows us to use callback method annotations like @PrePersist, @PostPersist,@PreUpdate with no extra configuration.

Using similar callbacks while using SessionFactory will require extra efforts.

Related Hibernate docs can be found here and here.

Related SOF Question and Spring Forum discussion

踏雪无痕 2024-11-07 20:49:11

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

EntityManagerFactory is the standard implementation, it is the same across all the implementations. If you migrate your ORM for any other provider like EclipseLink, there will not be any change in the approach for handling the transaction. In contrast, if you use hibernate’s session factory, it is tied to hibernate APIs and cannot migrate to new vendor.

时光病人 2024-11-07 20:49:11

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

javax.persistence.EntityManager

而不是

org.hibernate.ejb.HibernateEntityManager

类似地,对于 EntityManagerFactory,使用 javax 接口。这样,代码就松耦合了。如果有比 hibernate 更好的 JPA 2 实现,那么切换就会很容易。在极端情况下,我们可以将类型转换为 HibernateEntityManager。

By using EntityManager, code is no longer tightly coupled with hibernate. But for this, in usage we should use :

javax.persistence.EntityManager

instead of

org.hibernate.ejb.HibernateEntityManager

Similarly, for EntityManagerFactory, use javax interface. That way, the code is loosely coupled. If there is a better JPA 2 implementation than hibernate, switching would be easy. In extreme case, we could type cast to HibernateEntityManager.

很酷不放纵 2024-11-07 20:49:11

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文