代码之家  ›  专栏  ›  技术社区  ›  matt b

Hibernate、JPA和JDO——各自的优缺点?[关闭]

  •  178
  • matt b  · 技术社区  · 16 年前

    我对ORM这个概念很熟悉,几年前我甚至用过nHibernate。NET项目;然而,我还没有跟上Java中ORM的主题,也没有机会使用这些工具中的任何一个。

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

    我很难分辨JPA规范、Hibernate库本身和JDO所提供的内容之间的区别。

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

    • 每种方法的优缺点是什么?
    • 你对新项目有什么建议?
    • 在某些情况下,使用一个框架与另一个框架相比是有意义的吗?
    11 回复  |  直到 16 年前
        1
  •  112
  •   Stephen C    14 年前

    一些注意事项:

    • JDO和JPA都是规范,而不是实现。
    • 这个想法是,如果您将代码限制为仅使用标准JPA,则可以交换JPA实现。(JDO也是如此。)
    • Hibernate可以用作JPA的一个这样的实现。
    • 然而,Hibernate提供了一个原生的API,具有JPA之上和之上的功能。

    我推荐Hibernate。


    有一些评论/问题是关于如果你 需要 使用Hibernate特有的功能。有很多方法可以看待这个问题,但我的建议是:

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

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

    事实上,你可能需要权衡 多少 你担心与供应商的合作 多少 您需要这些特定于供应商的扩展。

    还有其他因素,比如你/你的员工对各自技术的了解程度,产品的许可成本,以及你相信JDO和JPA未来会发生什么。

        2
  •  69
  •   Community CDub    8 年前

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

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

    你可能会发现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移植到DataNucleu应该非常简单,您可以通过很少的代码更改(如果有的话)获得DataNucles的所有上述好处。 所以就问题而言,选择一个特定的标准,JPA(仅限RDBMS)vs JDO(RDBMS+无SQL+ODBMS+其他),DataNucleus支持两者,Hibernate仅限于JPA。

    Hibernate数据库更新的性能

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

        3
  •  54
  •   matt b    15 年前

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

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

    • 您可以使用非sql数据源、db4o、hbase、ldap、bigtable、couchdb(cassandra插件)等。
    • 您可以轻松地从sql数据源切换到非sql数据源,反之亦然。
    • 没有代理对象,因此在hashcode()和equals()实现方面的痛苦更小
    • 更多的POJO,因此需要更少的变通方法
    • 支持更多关系和字段类型

    以及支持 日本工程标准协会 主要是:

    • 更加受欢迎的
    • jdo死了
    • 不使用字节码增强

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

    我也看到了很多JDO用户的帖子,他们迁移到JDO,因此更快乐。

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

    JDO及其参考实现Datanucleus显然并没有死,谷歌将其用于GAE并积极开发源代码就证明了这一点(http://sourceforge.net/projects/datanucleus/).

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

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

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

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

    答案是,这取决于你想要什么。我宁愿有更干净的代码,没有供应商锁定,更面向pojo,nosql选项更受欢迎。

    如果你想感受到与大多数其他开发人员/绵羊一样的温暖挑剔的感觉,请选择JPA/hibernate。如果你想在你的领域领先,试试用JDO/Datanucleus并做出自己的决定。

        4
  •  40
  •   oxbow_lakes    16 年前

    你对新项目有什么建议?

    我建议两者都不要!使用Spring DAO JdbcTemplate 和…一起 StoredProcedure , RowMapper RowCallbackHandler 相反。

    我个人对Hibernate的经验是,前期节省的时间被你接下来花在理解和调试意外级联更新行为等问题上的无数天所抵消。

    如果你使用的是关系数据库,那么你的代码越接近它,你的控制力就越强。Spring的DAO层允许对映射层进行精细控制,同时消除了对样板代码的需求。此外,它集成到Spring的事务层中,这意味着您可以很容易地添加(通过AOP)复杂的事务行为,而不会侵入您的代码(当然,您也可以通过Hibernate获得此功能)。

        5
  •  23
  •   DataNucleus    16 年前

    JDO死了

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

    这是在Apache下公开开发的。JPA发布的版本比JPA多,其ORM规范甚至仍领先于JPA2提出的功能

        6
  •  15
  •   Sandeep Manne    15 年前

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

        7
  •  10
  •   Bruce Bruce    16 年前

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

        8
  •  8
  •   tapi    16 年前

    我自己也一直在研究这个问题,但找不到两者之间的明显区别。我认为最大的选择是使用哪种实现。就我个人而言,我一直在考虑 DataNucleus 平台,因为它是两者的数据存储无关实现。

        9
  •  8
  •   Volksman    15 年前

    任何说JDO已经死了的人都是胡说八道,他们知道这一点。

    JDO活得很好。该规范相较于更为年轻且受限的JPA,仍然更为强大、成熟且先进。

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

        10
  •  2
  •   Sean McCauliff    15 年前

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

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

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

        11
  •  1
  •   Torben Vesterager    12 年前

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

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

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