JPA和Hibernate有什么区别?

679

我了解JPA 2是一个规范,而Hibernate是一个ORM工具。此外,我知道Hibernate比JPA 2拥有更多功能。但从实践的角度来看,真正的区别是什么?

我有使用iBatis的经验,现在我正在尝试学习Hibernate或JPA2。我选择了《Pro JPA2》这本书,它一直在提到“JPA提供程序”。例如:

如果您认为某个功能应该被标准化,那么您应该向您的JPA提供程序请求它

这让我感到困惑,因此我有几个问题:

  • 只使用JPA2,我能否通过简单地注释我的POJO来从数据库中提取数据?
  • JPA2是否应该与“JPA提供程序”(例如TopLink或Hibernate)一起使用?如果是这样,使用JPA2 + Hibernate相对于仅使用JPA2或仅使用Hibernate有什么好处?
  • 您能推荐一本好的实用JPA2书籍吗?《Pro JPA2》似乎更像是关于JPA2的圣经和参考书(它直到后半部分才涉及查询)。是否有一本采用问题/解决方法论的JPA2书籍?

2
关于“JPA和Hibernate之间的区别”的问题是不正确的。Hibernate vs JPA的争论是毫无意义的。 建议使用任何实现JPA API的JPA,以避免实现不同的ORM。 - BERGUIGA Mohamed Amine
18
@Berguiga.M.Amine,如果我们已经知道上面的问题是不正确的,那么就不需要再问了。我对这个话题也很感兴趣。 - Raphaël Colantonio
我对在Spring中使用的JpaTemplate "org.springframework.orm.jpa.JpaTemplate"感到困惑,因为它有自己的函数,例如persist()、find()、merge()等等,那么没有Hibernate是如何工作的呢? - nitin verma
@nitinverma:这实际上是一个单独的问题。如果您仍然需要答案,我建议您单独提出自己的问题以吸引更多反馈。 - Wouter
22个回答

776
正如您所说,JPA只是一种规范,这意味着没有实现。您可以使用JPA注解对类进行注释,但是如果没有实现,什么都不会发生。将JPA视为必须遵循的指南或接口,而Hibernate的JPA实现是符合JPA规范定义的API的代码,并提供底层功能。
当您使用JPA与Hibernate时,实际上是在使用Hibernate JPA实现。其好处是,您可以将Hibernate的JPA实现替换为JPA规范的另一个实现。当您使用纯Hibernate时,由于其他ORM可能使用不同的方法/配置和注解,因此您无法轻松切换到另一个ORM。
要获取更详细的说明,请阅读我的博客文章

5
当您使用Hibernate与JPA时,{java.persistence}注释是否能够工作,还是您需要使用{org.hibernate}注释? - Bosco
意思是没有实现,但有具体的类,因此我们可以使用javax.persistence.entityManager.persist。 - merveotesi
62
我想补充一点,用不同的ORM替换一个ORM是非常罕见的情况,所以你可能永远无法从使用JPA中获得这种好处。使用JPA可以获得协议、标准、命名和其他约定,这些约定可以用于与他人进行沟通。 - pubsy
3
@pubsy 我同意,但原则上这是规范的卖点之一。 - Kevin Bowersox
6
回答你的问题,当使用Hibernate与JPA时,{java.persistence}注释将起作用,不需要使用{org.hibernate}注释。 - lowLatency
3
只要一个人的代码只使用了JPA中提到的接口,@JavaGeek所说的就是正确的。如果使用了特定于Hibernate的功能,则必须使用org.hibernate注释。 更多信息 - Suryavanshi

630

JPA是一种舞蹈,Hibernate是舞者。


2
嘿,但有人可以使用javax.persistence.entityManager而不是org.hibernate.session。 - merveotesi
7
但是,Dancer(Hibernate)可以在没有跳舞(JPA)的情况下执行,对吧 :/ - RevanthKrishnaKumar V.
3
这个答案并没有解释任何东西,只是一个模糊的说法。 - Amir Kost
11
这个比喻并没有增加理解。如果你已经知道差别,你会觉得很有趣。如果你不知道差别,你仍然不会知道它。 - Nick Volynkin
3
公正地说,这就是为什么它不是被接受的答案。话虽如此,我认为在阅读了被接受的答案后,再阅读这个答案,很清楚两者之间的区别。 - aug
显示剩余7条评论

158

有些东西如果没有历史语言背景和对JCP的了解是很难理解的。

通常会有第三方开发的包,执行某个功能或填补某个空缺,这些包不属于官方JDK的一部分。由于各种原因,这些功能可能通过JCP(Java社区流程)成为Java JDK的一部分。

Hibernate(在2003年)提供了一种抽象SQL的方法,允许开发人员更多地考虑持久化对象(ORM)。您通知Hibernate有关您的实体对象,它会自动生成持久化它们的策略。Hibernate提供了一个实现来完成这项任务,以及通过XML配置或注释驱动实现的API。

现在基本问题是,您的代码与特定供应商(Hibernate)紧密耦合,而许多人认为应该更通用。因此需要一个通用的持久性API。

同时,JCP在Hibernate和其他ORM工具供应商的大量输入下正在开发JSR 220(Java规范请求),其结果是JPA 1.0(2006),最终是JSR 317,即JPA 2.0(2009)。这些是通用Java Persistence API的规范。该API作为一组接口提供在JDK中,以便您的类可以依赖于javax.persistence而不用担心执行持久化对象的特定供应商。这只是API,而不是实现。Hibernate现在成为实现JPA 2.0规范的众多供应商之一。您可以编写针对JPA的代码,并选择适合您需要的任何兼容ORM供应商。

有些情况下,Hibernate可能会给您提供JPA中未规定的功能。在这种情况下,您可以选择直接在类中插入一个Hibernate特定注释,因为JPA不提供执行该操作的接口。

来源:http://www.reddit.com/r/java/comments/16ovek/understanding_when_to_use_jpa_vs_hibernate/


2
好的历史部分。而其他答案只是在重复问题中的内容。 - Robert
1
感谢您提供这些启示性的澄清。您说JPA是因为应用程序与Hibernate紧密耦合,需要抽象化,好的。但这不是一个无限的问题吗?现在应用程序与JPA密切耦合了,真正的好处在哪里?我已经将Hibernate视为抽象层... - Aphax
4
当你编写 .java 文件时,你也与 Java 紧密耦合,那么如果我明天想换成 Python 呢? - Smutje

100

JPA是接口,而Hibernate是实现。

传统上有多种Java ORM解决方案:

每个实现都定义了自己的映射定义或客户端API。JPA专家小组汇集了所有这些工具的优点,因此创建了Java Persistence API标准。

从客户端的角度来看,标准持久化API非常方便,可以相对容易地切换不同的实现(虽然在实践中并不简单,因为在大型项目中仍需要使用特定的非标准功能)。

标准JPA推动了Java ORM竞争到一个新的水平,这只会导致更好的实现。

我的书,High-Performance Java Persistence所述,Hibernate提供了JPA还不支持的功能

这些附加功能使Hibernate能够满足大型企业应用程序所需的许多持久化要求。


这是一个不错的工具,我之前不知道还有其他的ORM工具。 - Avdhut
非常好的答案,我非常喜欢这本书!感谢您的发布! - Jonas Schreiber
感谢您喜欢我的高性能Java持久化书籍。 - Vlad Mihalcea
这里的JPA是接口,而Hibernate是实现。 - Edward J Beckett

57

来源于维基百科

创建Java持久化API的动机

许多企业级Java开发人员使用由开源框架或数据访问对象提供的轻量级持久化对象,而不是实体Bean:实体Bean和企业Bean被认为过于笨重和复杂,并且只能在Java EE应用服务器中使用。第三方持久性框架的许多功能已并入Java Persistence API中,截至2006年,像Hibernate(版本3.2)和开源版本TopLink Essentials等项目已成为Java Persistence API的实现。

根据JCP页面所述,Eclipse Link是JPA的参考实现。有关此内容更多信息,请参见此答案

JPA本身具有构成标准ORM框架的功能。由于JPA是Java EE规范的一部分,您可以单独在项目中使用JPA,并且它应该适用于任何Java EE兼容服务器。是的,这些服务器将具有JPA规范的实现。

Hibernate是最流行的ORM框架,一旦引入JPA,Hibernate遵循JPA规范。除了应该遵循的基本规范外,Hibernate还提供了更多附加内容。


3
你的意思是在项目中可以单独使用JPA,是不是指不使用Hibernate、TopLink或其他任何JPA实现? - abbas
2
@abbas 是的。Java EE规范只使用JPA。如果您添加Hibernate,它会提供一些额外的功能。 - ManuPK
1
我听说JPA只是一个接口/规范。如果我们在项目中仅使用JPA,那么它的实现从哪里获取? - abbas
@abbas感谢您的评论。我在答案中添加了更多细节。希望这可以帮助到您。 - ManuPK
1
@Forhad 无论实现是否隐藏在某些服务器架构中,总是需要有一个实现。不能仅仅下载一些 JPA 库并让它为您执行持久化。 - Kevin Bowersox
显示剩余2条评论

15
JPA只是需要具体实现的规范。现在提供的默认实现是" Eclipselink",由Oracle提供。(Toplink被Oracle捐赠给Eclipse基金会与eclipselink合并)。
(参考:http://www.oracle.com/technetwork/middleware/toplink/index-085257.html http://www.eclipse.org/org/press-release/20080317_Eclipselink.php)
使用Eclipselink,可以确保代码在需要时可移植到任何实现中。Hibernate也是完整的JPA实现+更多(类似于JPA Plus)。Hibernate是具有一些额外Hibernate特定功能的JPA超集。因此,在切换到其他实现时,使用Hibernate开发的应用程序可能不兼容。尽管如此,Hibernate仍然是大多数开发人员作为JPA实现的选择,并且被广泛使用。
另一个JPA实现是OpenJPA(openjpa.apache.org),它是Kodo实现的扩展。

15

JPA : 类似于一个接口,没有具体的实现来使用其中存在的函数。

Hibernate : 是一个 JPA 提供者,它有 JPA 中函数的实现,并且可以拥有一些 JPA 中不存在的额外函数。

TIP:你可以使用

     *combo 1* : JPA + JPA Provider(Hibernate) 
     *combo 2* : only Hiberante which does not need any interface 

组合1:当您觉得您的Hibernate性能不佳并且想要更改JPA提供程序时,您无需重新编写JPA。您可以编写另一个JPA提供程序...并且可以随时更改。

组合2:很少使用,当您不打算以任何代价更改JPA提供程序时。

请访问http://blog-tothought.rhcloud.com//post/2,在那里您的所有疑惑都将得到解决。


11

JPA是接口,Hibernate是该接口的一个实现。


2
而且,Hibernate还添加了一些更多的功能/方法。 - rai.skumar

10

5

JPA只是一种规范。市场上有许多供应商实现了JPA。不同类型的供应商以不同的方式实现JPA,因此不同类型的供应商提供不同的功能,因此根据您的要求选择适当的供应商。

如果您使用的是Hibernate或任何其他供应商而不是JPA,则不能轻松地将Hibernate迁移到EclipseLink或将OpenJPA迁移到Hibernate。但如果您使用JPA,则只需在持久性XML文件中更改提供程序。因此,在JPA中轻松进行迁移是可能的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接