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


174

我对ORM这个概念很熟悉,几年前甚至在n.ibernate项目中使用nHibernate。但是,我没有跟上Java中ORM的话题,也没有机会使用任何这些工具。

但是,现在我可能有机会开始对我们的一个应用程序使用一些ORM工具,以尝试摆脱一系列旧式Web服务。

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

因此,我知道这个问题有点开放性,但是我希望就以下问题得到一些意见:

  • 各自的优缺点是什么?
  • 您对新项目有何建议?
  • 在使用一个框架与另一个框架时是否存在某些条件?

Answers:


112

一些注意事项:

  • JDO和JPA都是规范,而不是实现。
  • 这个想法是,如果您将代码限制为仅使用标准JPA,则可以交换JPA实现。(适用于JDO的同上。)
  • Hibernate可以用作JPA的一种实现。
  • 但是,Hibernate提供了本机API,具有超越JPA的功能。

海事组织,我建议休眠。


对于需要使用特定于Hibernate的功能时应采取的措施,已有一些意见/问题。有很多方法可以解决这个问题,但是我的建议是:

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

  • 如果您对供应商捆绑的前景感到担心,并且不能不借助供应商特定的扩展而使用JPA,则不要使用JPA。(适用于JDO的Ditto)。

在现实中,你可能需要权衡多少你被厂商担心搭配与多少,你需要这些供应商特定的扩展。

还有其他一些因素,例如您/您的员工对相关技术的了解程度,产品在许可方面的成本,以及您相信谁的故事对于JDO和JPA将来会发生什么。


8
工具包,不错,简短。值得一提的另一点是,JPA不会在必要时使用特定于实现的功能。这意味着当Hibernate是实现时,JPA允许您使用任何Hibernate功能。
topchef 2010年

1
如果我需要Hibernate的某些特定功能,使用JPA有什么好处?
布鲁诺·里斯

22
需要添加的重要说明:尽管JPA和JDO都对RDBMS提供了出色的支持,但是JDO与“数据存储”无关,因此不限于RDBMS。随着NoSQL的迅速发展,人们明智地考虑使用一种持久性标准,该标准避免将其应用程序锁定在传统的* SQL世界中。JDO应用程序可以轻松地部署到非RDBMS数据存储中。支持的数据存储的完整列表可在以下位置找到: datanucleus.org/products/accessplatform/datastores.html
Volksman,2010年

2
@Golfman为什么选择基于可能发生的情况?如果您最终确实需要NoSQL支持,则没有什么可以阻止您稍后再进行其他工作... KISS
TM。

1
@Bruno -当你使用Hibernate的非Hibernate的特定部分,你正在使用JPA。显然,将自己限制为纯JPA的好处是您可以更轻松地切换到另一个JPA实现。
斯蒂芬·C 2010年

69

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

与休眠相比,JDO / DataNucleus的另一个优点是它没有所有的运行时反射开销,并且由于使用了构建时间字节代码增强功能(对于大型项目,可能会增加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月更新

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

Hibernate DB更新的性能

选择ORM时要考虑的另一个问题是它的脏检查机制的效率-当它需要构造SQL以更新当前事务中已更改的对象时,这一点变得非常重要-尤其是当对象很多时。在此SO答案中有Hibernate脏检查机制的详细技术说明: 带有HIBERNATE的JPA插入速度非常慢


3
众所周知,增强正是JDO被如此广泛采用的原因!
Pascal Thivent

15
早期,关键的Hibernate参与者对JDO进行了广为宣传的FUD和草拟行为,这是不诚实和令人作呕的,无疑对JDO的采用产生了一些影响。如今,开发人员已经知道字节码增强根本不是问题,并且经常将其用于持久性以外的许多其他目的。新的ASM字节码增强库是如此之快,以至于您甚至没有时间在完成之前喘口气。
大众

7
从一开始就预测到JDO的失败(javalobby.org/forums/thread.jspa?forumID=46&threadID=1326),并且在Hibernate之前就已经失败了,因此您不能为此而怪罪于Hibernate。Hibernate / Toplink成功地解决了Sun和JDO播放器(及其OODBMS)失败的原因,因为当时他们是更好的答案,而不是因为市场营销和FUD。期。谁在乎ASM 今天是否在快速发展,而5年前还没有出现,当时需要时 JDO只是输掉了这场战斗。JDO在概念上优越吗?太糟糕了,它未能按时实施成功的实施方案(并且由于JPA而不会回来)。
Pascal Thivent 2010年

2
为了说明我的话(还有另一篇文章说明人们在开发过程中感到的痛苦或Hibernate为什么赢得了这场战斗):mail-archive.com/open-jpa-dev@incubator.apache.org/…。在我看来,反射/ cglib似乎是解决人们问题的切实可行的答案(并且人们并不在乎使用API​​是否在概念上优越,如果使用起来很麻烦),我在这里看不到任何Hibernate关键参与者,只是用户。所以最后我想知道到底是谁在传播FUD ...
Pascal Thivent 2010年

7
好吧,这肯定不像以前那样,那里至少有17个不同的Hibernate专业FUD帖子(但仅来自3个不同的IP地址。
大众

54

我最近评估并选择了一个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(和数据核实现)似乎是一个更安全的选择。

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

我发现开始使用Datanucleus的最初障碍有些棘手-datanucleus网站上的文档有些难以理解-教程并没有我想要的那么容易。话虽如此,一旦您走过了最初的学习过程,有关API和映射的更详细的文档就非常有用。

答案是,这取决于您想要什么。我宁愿使用更简洁的代码,没有供应商锁定,更倾向于pojo取向,nosql选项和更受欢迎。

如果您希望自己与大多数其他开发人员/绵羊一样在做事,请选择JPA /休眠。如果您想领导该领域,请测试JDO / Datanucleus,并下定决心。


9
实际上,就像我说的那样,我只是对尝试选择解决方案时所发现的内容给出了自己的印象。是的,我是Java的初学者,为什么那应该如此?另一方面,您已经发表了很多次声明,您认为JDO已死,却没有提供任何事实或证据来证实它,也没有承认JDO明显优越的技术领域。显然,您对JDO / Datanucleus有一些私人的东西,并且正在使用这些线程作为维持您的反JDO立场的手段。
汤姆

4
Pascal-您在这里争论自己。我认为您错过了常见问题解答广告部分的要点。OP要求对2种技术发表意见。它正在邀请支持双方的各方站出来提出自己的建设性批评/建议。对于Andy / Datanucleus和其他JDO用户而言,突出JDO的积极性并防止受到批评的广告并不比这里建议使用休眠模式的其他人多。
汤姆(Tom)2010年

5
您可能会很好地参考FAQ的“保持良好状态”部分,因为您在该主题上的帖子是蓄意,对抗或无礼的。您的第一个评论是关于增强的讽刺评论。第二; 对早期实施的困难的抱怨,不再相关。第三是对那些可能不想使用RDBMS的人的幼稚嘲讽和侮辱。第四是讽刺嘲笑一个对你有不同看法的人。第五是攻击;叫我一只鹦鹉。您是否认为这“很好”?
汤姆

3
如果您在JDO方面有过恐怖的经验,请解释什么是可怕的,承认它是早期版本,此后可能会有所改善。您还需要认识到其他人可能对您有不同的需求。仅仅因为您对JPA感到“满意”并且想要使用RDBMS并不意味着其他人也是如此。也许您急于提高自己的声誉,却忘记了要授予什么声誉?ps。作为开发人员,你应该真的有兴趣在这些项目的福祉因为这是推动创新并减少供应商锁定。
汤姆

6
这将是我的最后答复:) .. 1.如果不怀疑为什么要提出来?2.我从来没有质疑过你的诚实,我说过你对其他海报不友善,并且自相矛盾。3.没有人建议您总结8年以上-但要用事实和例子来支持您的陈述,而不要用可能会冒犯您的主观陈述。5.在这篇文章中,“休眠/ jpa / jboss是邪恶的”态度在哪里?我没看到。我只会看到您的反JDO评论。
汤姆(Tom)2010年

40

您对新项目有何建议?

我不建议!使用Spring DAO的JdbcTemplate一起StoredProcedureRowMapperRowCallbackHandler来代替。

我自己对Hibernate的亲身经历是,前期节省的时间已被无休止的日子所抵消,您将花费大量时间来尝试理解和调试问题,例如意外的级联更新行为。

如果您使用的是关系数据库,那么您的代码离它越近,您拥有的控制权就越大。Spring的DAO层允许对映射层进行精细控制,同时消除了对样板代码的需求。而且,它还集成到Spring的事务层中,这意味着您可以非常轻松地(通过AOP)添加复杂的事务行为,而不会干扰代码(当然,您也可以通过Hibernate获得它)。


4
显然,这是自ODBC时代(90年代初)(读取旧版)以来由大量用户和代码库累积驱动的反对象关系映射(ORM)选择。除非您选择继续使用ORM框架,否则没有理由不使用JDBC(带有或不带有Spring)。想想那些有一天决定放弃FORTRAN以使用C或Pascal的人。
topchef 2010年

23
@grigory-我有很多浪费时间尝试理解Hibernate问题的经验,例如级联的更新/删除,效率低下的查询结构等。对于那些对关系数据库的了解不足的人,ORM解决方案是“快速的胜利”。因此,仅了解Hibernate不可能产生良好的最终产品。根据我的经验,在项目生命周期中,Hibernate(以及扩展的ORM)所花费的时间多于所节省的时间
oxbow_lakes 2010年

8
很抱歉您在Hibernate方面的经验很差。我本人来自繁重的数据库/ SQL /存储过程/ JDBC学校。我不能说我会转换-上面的每种技术仍然有待发展的地方。但是对于通用Java 3层应用程序(无论大小),首选是ORM技术-最好是JPA2。应基于遗留代码,集成,专业知识,大量需求,实时等因素来考虑其他技术。性能等,可能会(或可能不会)使方法趋向于不同的数据库技术堆栈。
topchef 2010年

3
我完全不同意上面的“快速获胜”定义-只需抓住Hibernate in Action(stackoverflow.com/questions/96729/…)(它是JPA 1,而JPA 2只会变得更好),才能充分理解该技术的功能并涵盖该技术有。
topchef 2010年

7
我做了一些研究,Spring不再推荐Spring DAO的(static.springsource.org/spring/docs/3.0.x/…):“建议的集成样式是针对普通的Hibernate,JPA和JDO API编写DAO。不再建议使用旧的使用Spring DAO模板的样式;“ ...这是您所建议的吗?如果是这样,为什么他们不推荐呢?
User1

23

JDO死了

JDO实际上还没有死,所以请检查您的事实。JDO 2.2已于2008年10月发布。JDO2.3正在开发中。

这是在Apache下公开开发的。比JPA发行的版本更多,其ORM规范甚至比JPA2提议的功能还先进


12
人们肯定会使用它,正如许多用户所证明的那样,DataNucleus拥有,不用管Xcalia,Kodo。您会错过JDO和JPA不能满足同一市场的基本想法。JPA仅是RDBMS。JDO与数据存储区无关,并且用于RDBMS,但也用于LDAP,XML,Excel,OODBM等
DataNucleus

3
我喜欢非RDBMS的因素,特别是随着非RDBMS解决方案的普及,这很重要。这意味着,如果JPA的发展速度不够快,那么“更加开放”和灵活的替代方案(JDO)的可用性意味着JPA的受欢迎程度将由于不必要而呈下降趋势。不用担心JDO更完整,更高级,更成熟或其他方面的技术论点-这不是优先考虑的问题。RDBMS供应商的表现令人怀疑-RDBMS市场支配地位的时代可能即将终结。
Manius

我们在2019年仍在使用JDO / DataNucleus!现在,它的版本达到了5.x,在开发人员的生产率和运行时性能方面仍胜过Hibernate。最近,我不得不使用Hibernate在大型Web应用程序上进行一些咨询,这使我想起很多年前我是活跃的HIbernate用户和发起人时所遭受的痛苦。当我告诉她她的BLOB领域时,团队负责人不相信我即使被标记为“懒惰获取”,也总是热切地获取。一位自称“经验丰富”的Hibernate专家完全缺乏“幕后知识”,这令人遗憾,但令人期待。
Volksman


10

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


9

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

JDO仍然健在。与更年轻,受约束的JPA相比,该规范仍然更强大,更成熟,更先进。

如果您希望仅使用JPA标准中提供的功能,则可以编写JPA并将DataNucleus用作比JPA其他实现更高性能,更透明的持久性实现。当然,如果您想要JDO带来的建模的灵活性和效率,DataNucleus也可以实现JDO标准。


1
或者,您使用另一个(更好的)实现,它具有更大,因此响应更快的社区。是的,有些人也这样做。
Pascal Thivent 2010年

1
您谈论FUD> :)有趣。
Pascal Thivent 2010年

2
您的评论似乎假设我没有同时使用Hibernate和JDO。
大众

2
这个线程似乎有很多人提到了DataNucleus的出色表现。请不要将此地方用作您的广告平台。
TM。

3
戈尔夫曼毫不奇怪,他在涉及JPA或DataNucleus的每个线程中不断地重复粘贴同样绝望的营销资料(他从1996年开始使用,直到它还没有出现!)。
Pascal Thivent

8

我本人一直在研究此问题,因此找不到两者之间的重大区别。我认为最大的选择是使用哪种实现。对于我自己,我一直在考虑DataNucleus平台,因为它是两者的数据存储不可知的实现。


6
+1用于DataNucleus,而不是答案。
WolfmanDragon

2

我在同一项目中使用了Hibernate(JPA实现)和JPOX(JDO实现)。JPOX可以正常工作,但是很快就遇到了bug,那里是当时不支持的Java 5语言功能。在与XA事务配合时,存在一些问题。我从JDO对象生成数据库架构。它想每次都连接到数据库,这很烦人,如果您的Oracle连接不起作用。

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

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


1
据我所知,JPOX将名称更改为DataNucleus(此后已发布)。
Donal Fellows 2010年

2
认为您实际上会发现DataNucleus的开放式错误比您所引用的其他软件要少。认为您还会发现DataNucleus开发也以比其他软件更快的速度减少了错误数量。
DataNucleus

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.