使用休眠 sessionFactory 或 JPA entityManager?

Posted

技术标签:

【中文标题】使用休眠 sessionFactory 或 JPA entityManager?【英文标题】:Use hibernate sessionFactory or JPA entityManager? 【发布时间】:2013-01-13 23:40:09 【问题描述】:

我正在开发一个使用 Hibernate 4.1、Spring 3.1 和 JPA 2.0 的项目,我想验证我从互联网上收集到的信息是否正确。

我正在尝试决定是使用 JPA entityManager 还是使用特定于休眠的 sessionFactory。

起初我计划使用 entityManager 和完整的 JPA 规范,因此我的项目将与 Hibernate 解耦,如果后来有什么想法让我信服,我可以把它换成其他东西,比如 EclipseLink。

然而,entityManager 似乎有一些非常重要的限制。

我的问题:

我想使用完整的 JPA 规范和 entityManager 的唯一原因是能够相对轻松地为不同的 JPA 2.0 兼容 ORM 切换 Hibernate,对吗?使用 entityManager 真的没有性能/功能/易于编程的好处吗?

其次,hibernate sessionFactory 似乎比 entityManager 有很多好处。到目前为止,我遇到了 entityManager 无法执行实体列表的批量插入的问题,我读过 sessionFactory 可以。我还读到 sessionFactory 可以自动返回一个自动生成的实体 ID,而使用 entityManager 您需要结束事务/刷新持久性上下文以提取新生成的 ID。

我喜欢我的项目与 Hibernate 相对分离的想法,但我更希望能够从一开始就编写高效的数据库更新。所以我应该切换到为 hibernate 和 sessionFactory 配置的项目,对吗?

【问题讨论】:

以下答案建议使用entityManager,并在您有特定需求时将其解包到sessionFactory...***.com/questions/5640778/… 这似乎有点奇怪,要么你想坚持标准并且只使用entityManager,或者你知道你更喜欢Hibernate的特定功能并且只使用sessionFactory... 是的,这是个好主意。如果这样做有任何问题,我想有人会在那个线程中提到它。此外,我确实找到了一种让 entityManager 看起来更好的方法。它有 TypedQuery,我认为你不能在会话中使用它。 Coray,你最后用了什么?真的没有一个优于另一个的性能优势吗? 我现在做了一些项目。我主要使用 JPA entityManager,但我仍然认为没有任何实际的理由这样做。不过,我现在更习惯于使用它,而且我认为它不会有很大的不同(除非你真的需要批量插入东西!)我实际上更喜欢现在使用 Spring Data。它比其他任何一个选项都简化了很多。 【参考方案1】:

我会坚持使用 JPA2,就像你会使用 List 而不是 ArrayList:你更喜欢接口(或抽象)而不是实现。除了 HQL 知道比 JPQL 或外来特性“更多”的东西之外,没有太大区别。还要记住 JPA 是在 Hibernate 之后制作的,而 Hibernate 是 JPA 背后的“灵感”。

对于奇异的特性:Hibernate Entity Manager 包装一个 Hibernate Session。如果你真的需要它们,你可以将 EntityManager 转换为 Hibernate 接口 (org.hibernate.jpa.HibernateEntityManager),然后使用该会话。但如果我说我试过了,那我就是在骗你。

我还评论了你的部分问题:

我想使用完整的 JPA 规范和 entityManager 是为了能够将 Hibernate 切换为不同的 JPA 2.0 兼容 ORM 比较容易吧?真的没有吗 性能/功能/易于编程使用的好处 实体管理器?

从 Hibernate 切换到 EclipseLink 并不意味着您“只需要交换 jar”。映射和注释解析不一样,您会遇到可能会阻止您切换的问题。

您可以阅读my question here,了解我在使用两者时遇到的问题示例(这是一个 maven 项目,其配置文件可将 JPA2.1 impl 从 EclipseLink 切换到 Hibernate)。我放弃了 EclipseLink,因为我无法像我想要的那样命名数据库对象(或者更确切地说,指定数据库对象的名称)。

其次,hibernate sessionFactory似乎有很多 优于 entityManager。到目前为止,我遇到了这个问题 entityManager 无法执行实体列表的批量插入, 我读过 sessionFactory 可以。我也读过 sessionFactory 可以自动返回一个自动生成的实体 ID, 而使用 entityManager 您需要结束事务/刷新 拉取新生成的 id 的持久化上下文。

这取决于您如何生成实体 ID。但是想一想:在持久化上下文需要持久化它之前,您的实体不会持久化。这就是你没有身份证的原因。刷新它,也就是发送带有生成 id 的插入查询,是唯一的方法。

这同样适用于会话工厂。

不过,您或许可以从 Hibernate 访问序列生成器,但您也可以在本机 SQL 中使用 EntityManager 进行此操作。

我喜欢我的项目相对分离的想法 Hibernate,但我更希望能够编写高效的数据库 从一开始就更新。所以我应该切换到我的项目 为hibernate和sessionFactory配置的吧?

您可以将其视为针对 ORM 的巨魔,但为了高效的数据库更新,请使用普通 JDBC(或 Spring Jdbc 模板)。至少您会知道数据何时会更新,并且您将能够更好地优化(批量更新等)。

【讨论】:

【参考方案2】:

JPA 是 Hibernate 上的一个接口,它是 jdbc 上的一个接口,因此您离 jdbc 越近,您对查询的控制就越多,但您离对象/关系持久性越远。 是的,Hibernate 可能有一些 jpa 目前可能没有提供的工具(即休眠空间) Hibernate 很有趣,并且可以使用 JPA 注释来映射域模型(如果您使用 .hbm 文件上的注释方式)。 @Transactional 注释在 Spring 中的工作方式无论您使用 hibernate 还是 jpa 都无关紧要,因为您不需要 session.open() ... session.beginTranscation ...session.close ...etc ...所有这些冗长休眠代码不见了! 有关于 Hibernate 的很棒的文档和很棒的书籍。至于 JPA,我不能说我找到了 umber 书……

【讨论】:

以上是关于使用休眠 sessionFactory 或 JPA entityManager?的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate Sessionfactory 重启 |春天

在 Hibernate/JPA 中,我应该在哪里以及在哪个用例中使用 SessionFactory 和 Session

会话会话= sessionFactory.openSession();是不是在休眠

对于常规 java 类,休眠 sessionFactory 在我的 DAO 中始终为空

要使用的Hibernate或JPA注释

使用注解或使用休眠配置文件休眠