ChatGPT解决这个技术问题 Extra ChatGPT

Hibernate vs JPA vs JDO - 各自的优缺点? [关闭]

关闭。这个问题需要更加集中。它目前不接受答案。想改进这个问题?更新问题,使其仅通过编辑此帖子专注于一个问题。 7年前关闭。改进这个问题

我熟悉 ORM 作为一个概念,几年前我什至在 .NET 项目中使用过 nHibernate;但是,我没有跟上 Java 中的 ORM 的主题,也没有机会使用这些工具中的任何一个。

但是,现在我可能有机会开始为我们的一个应用程序使用一些 ORM 工具,试图摆脱一系列遗留的 Web 服务。

我很难说出 JPA 规范、您从 Hibernate 库本身获得的内容以及 JDO 必须提供的内容之间的区别。

所以,我知道这个问题有点开放,但我希望得到一些意见:

各自的优缺点是什么?

你会为一个新项目推荐哪个?

是否存在某些情况下使用一个框架而不是另一个框架才有意义?


S
Stephen C

一些注意事项:

JDO 和 JPA 都是规范,而不是实现。

这个想法是,如果您将代码限制为仅使用标准 JPA,您可以交换 JPA 实现。 (同样适用于 JDO。)

Hibernate 可以用作 JPA 的一种此类实现。

然而,Hibernate 提供了一个原生 API,其特性超越了 JPA。

IMO,我会推荐 Hibernate。

如果您需要使用特定于 Hibernate 的功能,有一些关于您应该做什么的评论/问题。有很多方法可以解决这个问题,但我的建议是:

如果您不担心与供应商合作的前景,那么请在 Hibernate 和其他 JPA 和 JDO 实现(包括您决策中的各种供应商特定扩展)之间做出选择。

如果您担心与供应商合作的前景,并且如果不求助于供应商特定的扩展就无法使用 JPA,那么请不要使用 JPA。 (JDO 同上)。

实际上,您可能需要权衡您对供应商绑定的担忧程度与您需要这些供应商特定扩展的程度。

还有其他因素,例如您/您的员工对各自技术的了解程度、产品的许可成本以及您认为 JDO 和 JPA 未来会发生什么的故事。


工具包,又好又短。值得一提的另一点是,JPA 不会阻止在必要时使用特定于实现的功能。这意味着当 Hibernate 是一种实现时,JPA 允许您使用任何 Hibernate 功能。
如果我需要 Hibernate 的某些特定功能,使用 JPA 有什么好处?
应该添加的重要说明:虽然 JPA 和 JDO 都对 RDBMS 提供了出色的支持,但 JDO 与“数据存储”无关,因此不限于 RDBMS 世界。随着 NoSQL 的迅速发展,人们明智地考虑使用持久性标准,以避免将他们的应用程序锁定在传统的 *SQL 世界中。 JDO 应用程序可以很容易地部署在非 RDBMS 数据存储中。可在以下位置找到支持的数据存储的完整列表:datanucleus.org/products/accessplatform/datastores.html
@Golfman 为什么要根据可能发生的情况进行选择?如果您最终需要 NoSQL 支持,那么没有什么可以阻止您稍后再加入其他东西... KISS
@Bruno - 当您使用 Hibernate 的非 Hibernate 特定部分时,您正在使用 JPA。显然,将自己限制为纯 JPA 的好处是可以更轻松地切换到另一个 JPA 实现。
C
Community

确保评估 JDO 的 DataNucleus 实现。我们从 Hibernate 开始,因为它看起来很流行,但很快意识到它不是 100% 透明的持久性解决方案。有太多警告,文档中充满了“如果你遇到这种情况,那么你必须像这样编写代码”,这剥夺了我们想要的自由建模和编码的乐趣。 JDO 从未让我调整我的代码或模型以使其“正常工作”。我可以设计和编写简单的 POJO,就好像我打算只在“内存中”使用它们一样,但我可以透明地持久化它们。

JDO/DataNucleus 相对于 hibernate 的另一个优势是它没有所有的运行时反射开销,并且内存效率更高,因为它使用构建时间字节码增强(可能为大型项目的构建时间增加 1 秒)而不是比休眠的运行时反射驱动的代理模式。

您可能会发现 Hibernate 令人讨厌的另一件事是,您必须对您认为的对象进行引用……它通常是对象的“代理”。如果没有字节码增强的好处,代理模式需要允许按需加载(即当您拉入顶级对象时避免拉入整个对象图)。准备好覆盖 equals 和 hashcode,因为您认为您正在引用的对象通常只是该对象的代理。

这是一个使用 Hibernate 时会遇到的挫败感的示例,而使用 JDO 时不会遇到这样的问题:

http://blog.andrewbeacock.com/2008/08/how-to-implement-hibernate-safe-equals.html
http://burtbeckwith.com/blog/?p=53

如果您喜欢编写“变通办法”,那么 Hibernate 肯定适合您。如果您喜欢干净、纯粹、面向对象、模型驱动的开发,您将所有时间都花在建模、设计和编码上,而没有花在丑陋的变通方法上,那么请花几个小时评估 JDO/DataNucleus。投入的时间将得到一千倍的回报。

2017 年 2 月更新

很长一段时间以来,除了 JDO 持久性标准之外,DataNucleus 还实现了 JPA 持久性标准,因此将现有的 JPA 项目从 Hibernate 移植到 DataNucleus 应该非常简单,您只需很少的代码更改即可获得 DataNucleus 的所有上述好处,如果有的话。因此,就问题而言,特定标准的选择,JPA(仅限 RDBMS)与 JDO(RDBMS + 无 SQL + ODBMSes + 其他),DataNucleus 支持两者,Hibernate 仅限于 JPA。

Hibernate DB 更新的性能

选择 ORM 时要考虑的另一个问题是其脏检查机制的效率——当它需要构造 SQL 来更新当前事务中已更改的对象时——尤其是当有很多对象时,这一点变得非常重要。在这个 SO 答案中有对 Hibernate 脏检查机制的详细技术描述:JPA with HIBERNATE insert very slow


众所周知,增强正是 JDO 被如此广泛采用的原因!
早期 Hibernate 的主要参与者在 JDO 方面广为人知的 FUD 和 astroturfing 简直是不诚实和令人作呕的,无疑对 JDO 的采用产生了一些影响。如今,开发人员知道字节码增强根本不是问题,并且经常将其用于除持久性之外的许多不同目的。新的 ASM 字节码增强库速度如此之快,您甚至来不及喘口气就完成了。
JDO 的失败从一开始 (javalobby.org/forums/thread.jspa?forumID=46&threadID=1326) 就在 Hibernate 之前就已经预料到了,因此您不能为此责怪 Hibernate。 Hibernate/Toplink 在 Sun 和 JDO 参与者(以及他们的 OODBMS)失败的地方取得了成功,因为当时它们是更好的答案,而不是因为营销和 FUD。时期。谁在乎 ASM 是否在今天迅速发展,5 多年前还没有,在需要时,JDO 只是输掉了这场战斗。 JDO 在概念上更胜一筹?太糟糕了,它未能按时获得优胜者实施(并且由于 JPA 而不会回来)。
为了说明我的话(另一篇文章说明了人们在开发过程中感受到的痛苦或为什么 Hibernate 确实赢得了这场战斗):mail-archive.com/open-jpa-dev@incubator.apache.org/…。在我看来,反射/cglib 是对人们问题的实用解决方案似乎很明显(如果使用起来很痛苦,人们并不关心 API 在概念上是否优越)而且我在这里看不到任何 Hibernate 关键参与者,只有用户.所以最后我想知道到底是谁在传播 FUD……
好吧,这肯定不像过去会有至少 17 个不同的专业 Hibernate FUD 帖子(但仅来自 3 个不同的 IP 地址。做数学的人 =))。
m
matt b

我最近评估并选择了一个 java 项目的持久性框架,我的发现如下:

我看到的是对 JDO 的支持主要是:

您可以使用非 sql 数据源、db4o、hbase、ldap、bigtable、couchdb(cassandra 插件)等。

您可以轻松地从 sql 数据源切换到非 sql 数据源,反之亦然。

没有代理对象,因此在 hashcode() 和 equals() 实现方面的痛苦更少

更多 POJO,因此需要更少的变通方法

支持更多的关系和字段类型

对 JPA 的支持主要是:

更流行

jdo死了

不使用字节码增强

我看到很多来自 JPA 开发人员的支持 JPA 的帖子,他们显然没有使用过 JDO/Datanucleus,他们为不使用 JDO 提供了薄弱的论据。

我还看到很多来自 JDO 用户的帖子,他们已经迁移到 JDO 并且因此更快乐。

关于 JPA 更受欢迎,这似乎部分是由于 RDBMS 供应商的支持,而不是它在技术上的优势。 (对我来说听起来像 VHS/Betamax)。

JDO 和它的参考实现 Datanucleus 显然没有死,正如 Google 将它用于 GAE 并积极开发源代码 (http://sourceforge.net/projects/datanucleus/) 所示。

由于字节码增强,我看到了许多关于 JDO 的投诉,但还没有解释为什么它不好。

事实上,在一个越来越痴迷于 NoSQL 解决方案的世界中,JDO(和 datanucleus 实现)似乎是一个更安全的选择。

我刚刚开始使用 JDO/Datanucleus 并对其进行了设置,以便我可以在使用 db4o 和 mysql 之间轻松切换。使用 db4o 有助于快速开发,而不必过多担心 DB 模式,然后,一旦模式稳定,就可以部署到数据库。我也有信心,以后,我可以将我的全部/部分应用程序部署到 GAE 或利用分布式存储/map-reduce a la hbase /hadoop / cassandra,而无需进行太多重构。

我发现开始使用 Datanucleus 的最初障碍有点棘手——datanucleus 网站上的文档有点难以理解——教程并不像我希望的那样容易理解。话虽如此,一旦您越过了最初的学习曲线,关于 API 和映射的更详细的文档就会非常好。

答案是,这取决于你想要什么。我宁愿拥有更简洁的代码、无供应商锁定、更面向 pojo、nosql 选项而不是更受欢迎的选项。

如果您想要和大多数其他开发人员/绵羊一样的温暖挑剔感觉,请选择 JPA/hibernate。如果您想在您的领域中处于领先地位,请试用 JDO/Datanucleus 并做出自己的决定。


实际上,就像我说的那样,我只是在尝试选择解决方案时给出我发现的东西的印象。是的,我是 Java 的初学者,为什么要那么相关?另一方面,您多次发表您的观点,即 JDO 已死,但没有提供任何事实或证据来证实这一点,也没有承认 JDO 明显优于的技术领域。您显然对 JDO/Datanucleus 有一些个人意见,并且正在使用这些线程作为使您的反 JDO 立场永久化的一种手段。
帕斯卡 - 你在这里争论自己陷入了困境。我认为您错过了常见问题解答中广告部分的要点。 OP 就 2 种技术征求意见。它邀请支持任何一方的人站出来提出建设性的批评/建议。对于 Andy/Datanucleus 和其他 JDO 用户来说,强调 JDO 的积极性并抵制批评与这里的其他人推荐使用 hibernate 一样,只不过是做广告而已。
您最好参考常见问题解答中“友善”的部分,因为您在该主题上的帖子是指责性的、对抗性的或粗鲁的。你的第一个是关于增强的讽刺评论。第二;对早期实施困难的咆哮,不再相关。第三是对那些可能不喜欢使用 RDBMS 的人的幼稚的嘲弄和侮辱。第四是对与你有不同看法的人的讽刺嘲讽。第五是攻击;叫我鹦鹉。你认为这是“善良”吗?
如果您对 JDO 有过可怕的经历,请解释什么是可怕的,承认它是在较早的版本中出现的,并且从那时起事情可能已经有所改进。您还需要认识到其他人可能对您有不同的需求。仅仅因为您对 JPA 感到“满意”并且想要使用 RDBMS 并不意味着其他人也一样。也许在你急于提高你的声誉时,你已经忘记了这个声誉可以奖励什么?附言。作为开发人员,您应该真正对此类项目的福祉感兴趣,因为这是推动创新并减少供应商锁定的因素。
这将是我的最后回应 :) .. 1. 如果不问为什么要提出这个问题? 2.我从来没有质疑过你的诚实,我说你对其他海报不友好,你自相矛盾。 3. 没有人建议你总结 8 年多的时间——但要用事实和例子来支持你的陈述,而不是可能会冒犯的主观陈述。 5. 这篇文章中的“hibernate/jpa/jboss 是邪恶的”态度在哪里?我没看到。我只看到你的反 JDO 评论。
o
oxbow_lakes

你会为一个新项目推荐哪个?

我都不建议!将 Spring DAO 的 JdbcTemplateStoredProcedureRowMapperRowCallbackHandler 一起使用。

我自己对 Hibernate 的个人经验是,预先节省的时间远远超过了您将花费无数天试图理解和调试问题(例如意外的级联更新行为)的时间。

如果您使用的是关系数据库,那么您的代码越接近它,您拥有的控制权就越大。 Spring 的 DAO 层允许对映射层进行精细控制,同时无需样板代码。此外,它集成到 Spring 的事务层中,这意味着您可以非常轻松地添加(通过 AOP)复杂的事务行为,而不会侵入您的代码(当然,您也可以使用 Hibernate 来实现这一点)。


这显然是反对象关系映射 (ORM) 的选择,由自 ODBC 时代(90 年代初)以来积累的大量用户和代码库驱动(阅读旧版)。除非您选择继续使用 ORM 框架,否则没有理由不使用 JDBC(有或没有 Spring)。想想那些曾经决定放弃 FORTRAN 以使用 C 或 Pascal 的人。
@grigory - 我有很多浪费时间试图理解Hibernate问题的经验,例如级联更新/删除,效率低下的查询结构等。对于那些对关系数据库了解不足的人来说,ORM解决方案是一种“速赢”。因此,仅对 Hibernate 的了解不太可能产生好的最终产品。根据我的经验,在项目生命周期中,Hibernate(以及扩展的 ORM)花费的时间多于节省的时间
很抱歉,您对 Hibernate 的体验如此糟糕。我自己来自重型数据库/SQL/存储过程/JDBC 学校。我不能说我是皈依者——上面的每一项技术都有一席之地。但是对于通用 Java 3 层应用程序(无论大小),首选是 ORM 技术 - 最好是 JPA 2。其他的要考虑基于这些因素遗留代码、集成、专业知识、批量繁重的要求、实时性能等,这可能会引导(或不引导)不同的数据库技术堆栈的方法。
我完全不同意上面的“速赢”定义——只要抓住 Hibernate in Action (stackoverflow.com/questions/96729/…)(它是 JPA 1,JPA 2 只会变得更好),以充分了解这项技术的功能和覆盖范围。
我做了一些研究,Spring 不再推荐 Spring DAO (static.springsource.org/spring/docs/3.0.x/…):“推荐的集成风格是针对普通的 Hibernate、JPA 和 JDO API 编写 DAO。不再推荐使用 Spring 的 DAO 模板的旧风格; “……这就是你推荐的吗?如果是这样,他们为什么不推荐它?
D
DataNucleus

JDO 已死

JDO 实际上并没有死,所以请检查你的事实。 JDO 2.2 于 2008 年 10 月发布 JDO 2.3 正在开发中。

这是在 Apache 下公开开发的。比 JPA 发布的版本更多,其 ORM 规范甚至领先于 JPA2 提议的特性


人们肯定在使用它,正如 DataNucleus 拥有的许多用户所证明的那样,更不用说 Xcalia、Kodo。您错过了 JDO 和 JPA 没有填补同一个市场的基本想法。 JPA 是专门的 RDBMS。 JDO 与数据存储无关,可用于 RDBMS,也可用于 LDAP、XML、Excel、OODBM 等
我喜欢非 RDBMS 因素,特别是随着非 RDBMS 解决方案的普及,这很重要。这意味着如果 JPA 发展不够快,“更开放”和更灵活的替代方案 (JDO) 的可用性意味着 JPA 的受欢迎程度将呈下降趋势,这是不必要的。不要介意 JDO 更完整、更优越、更成熟或其他什么的技术论点——这不是偏好问题。 RDBMS 供应商的行为可疑是有道理的——RDBMS 市场主导地位的日子可能即将结束。
2019 年我们仍在使用 JDO/DataNucleus!它现在升级到 5.x 版,并且在开发人员生产力和运行时性能方面仍然优于 Hibernate。最近我不得不在一个使用 Hibernate 的大型 Web 应用程序上做一些咨询,这让我想起了我多年前作为活跃的 HIbernate 用户和推广者时所遭受的痛苦,当我告诉她她的 BLOB 领域时,一位团队负责人不相信我即使它被标记为惰性获取,也总是急切地获取。一位“经验丰富”的自称 Hibernate 专家完全缺乏“幕后”知识,这令人遗憾,但在意料之中。
S
Sandeep Manne

JDO 具有比 JPA 更高级的功能,请参阅 http://db.apache.org/jdo/jdo_v_jpa.html


非常真实!但是好像没有人知道...
佚名

我正在使用 JPA(来自 Apache 的 OpenJPA 实现,它基于 5 年以上历史且非常快速/可靠的 KODO JDO 代码库)。恕我直言,任何告诉您绕过规范的人都会给您不好的建议。我投入了时间,肯定得到了回报。使用 JDO 或 JPA,您可以通过最少的更改更改供应商(JPA 具有 orm 映射,因此我们在不到一天的时间内就可能更改供应商)。如果您像我一样有 100 多张桌子,那将是巨大的。另外,您还可以通过集群方式缓存驱逐获得内置缓存,这一切都很好。 SQL/Jdbc 非常适合高性能查询,但透明持久性更适合编写算法和数据输入例程。我的整个系统中只有大约 16 个 SQL 查询(50k+ 行代码)。


t
tapi

我自己一直在研究这个,找不到两者之间的明显区别。我认为最大的选择是您使用哪种实现方式。对于我自己,我一直在考虑 DataNucleus 平台,因为它是两者的数据存储不可知的实现。


为 DataNucleus +1,而不是为答案。
V
Volksman

任何说 JDO 已死的人都是 astroturfing FUD 贩子,他们知道这一点。

JDO 活得很好。该规范仍然比更年轻和受限制的 JPA 更强大、更成熟和更先进。

如果您只想将自己限制在 JPA 标准中可用的内容,您可以写入 JPA 并使用 DataNucleus 作为高性能、比其他 JPA 实现更透明的持久性实现。当然,如果您想要 JDO 带来的建模灵活性和效率,DataNucleus 也实现了 JDO 标准。


或者你使用另一个(精细的)实现,它的社区更大,因此响应速度更快。是的,有些人也关心这个。
而你谈论 FUD > :) 很有趣。
您的评论似乎假定我没有同时使用 Hibernate 和 JDO。
这个线程似乎有很多人提到 DataNucleus 有多棒。请不要将此地方用作您的广告平台。
Golfman 在涉及 JPA 或 DataNucleus 的每个线程中一遍又一遍地粘贴同样令人绝望的营销材料,这并不令人惊讶(他在 it even existed 之前使用的是 since 1996!)。
S
Sean McCauliff

我在同一个项目中使用了 Hibernate(JPA 实现)和 JPOX(JDO 实现)。 JPOX 工作正常,但很快就遇到了错误,其中一些 Java 5 语言功能当时不支持。它在处理 XA 事务时遇到了问题。我正在从 JDO 对象生成数据库模式。它每次都想连接到数据库,如果您的 Oracle 连接发生故障,这很烦人。

然后我们切换到休眠。我们玩弄了一段时间只使用纯 JPA,但我们需要使用一些 Hibernate 特定功能来进行映射。在多个数据库上运行相同的代码非常容易。 Hibernate 似乎积极地缓存对象,或者有时只是有奇怪的缓存行为。有一些 DDL 结构 Hibernate 无法处理,因此它们被定义在一个附加文件中,该文件运行以初始化数据库。当我遇到 Hibernate 问题时,通常会有很多人遇到相同的问题,这使得在谷歌上搜索解决方案变得更容易。最后,Hibernate 似乎设计良好且可靠。

其他一些响应者建议只使用 SQL。对象关系映射的真正杀手级用例是测试和开发。为处理大量数据而构建的数据库通常很昂贵,或者很难安装。它们很难测试。有大量内存中的 Java 数据库可用于测试,但通常对生产毫无用处。能够使用真实但有限的数据库将提高开发效率和代码可靠性。


据我所知,JPOX 更名为 DataNucleus(从那时起就发布了)。
认为您实际上会发现 DataNucleus 的开放错误比您所指的其他软件少得多。认为您还会发现 DataNucleus 开发也以比其他软件更快的速度减少错误数量。
T
Torben Vesterager

我在 2012 年 5 月制作了一个示例 WebApp,它使用 JDO 3.0 & DataNucleus 3.0 - 看看它有多干净:https://github.com/TorbenVesterager/BadAssWebApp

好吧,也许它有点太干净了,因为我将 POJO 用于数据库和 JSON 客户端,但这很有趣 :)

PS:包含一些 SuppressWarnings 注释(在 IntelliJ 11 中开发)