代码之家  ›  专栏  ›  技术社区  ›  Henrik Paul

Hibernate或TopLink的替代方案?[闭门]

  •  6
  • Henrik Paul  · 技术社区  · 16 年前

    问题主要是延迟加载。由于在初始化和实际加载惰性集合之间可能存在多个HTTP请求,因此每个事务不可能有一个会话。长期会话(每个应用程序一个)也不能很好地工作,因为一旦事务遇到障碍并抛出异常,整个会话就会失效,因此延迟加载的对象就会中断。还有各种各样的东西不适合我们(比如隐式数据持久化来自初始化事务外部的数据)。

    撇开我糟糕的解释不谈,最重要的是Hibernate具有我们不喜欢的魔力。TopLink似乎没有任何改进,它也是在EJB之上编写的。

    因此,我们最需要的是无状态持久层(甚至是足够明亮的面向对象数据库抽象层)。

    编辑: 我为我含糊不清的术语感到抱歉,并感谢你们所有人的更正和富有洞察力的回答。那些纠正我的人,你们都是对的,我指的是JPA,不是EJB。

    11 回复  |  直到 16 年前
        1
  •  7
  •   cletus    16 年前

    如果您正在寻找另一个JPA提供商(Hibernate就是其中之一),那么看看 EclipseLink . 它的功能远比ToplinkEssentials的JPA1.0参考实现更全面。事实上,EclipseLink将是GlassFishV3最终版附带的JPA2.0参考实现。

    如果你想要的是更轻的重量的解决方案,那么只需 ibatis 我认为这是java平台的持久化技术。它是轻量级的,依赖于SQL(ORM用户花了多少时间试图让他们的ORM生成好的SQL,这令人惊讶),并且完成了JPA 90-95%的工作(如果您愿意,包括延迟加载相关实体)。

    只需纠正几点:

    • JPA是EJB的体验层,而不是构建在EJB上;
    • 任何一个像样的JPA提供商都有大量的缓存,很难完全弄清楚(这是一个很好的例子,说明“为什么简单这么复杂?”)。除非您正在做一些您没有指示的事情,否则异常不应该成为托管对象的问题。运行时异常通常回滚事务(如果您使用Spring的事务管理,谁不这么做?)。提供程序将维护已加载或持久化对象的缓存副本。如果要在实体管理器之外进行更新(需要显式缓存刷新或使用 EntityManager.refresh()
        2
  •  6
  •   Will Hartung    16 年前

    如前所述,JPA<&燃气轮机;EJB,它们甚至没有关联。EJB3碰巧利用了JPA,但仅此而已。我们有一大堆使用JPA的东西,甚至都不接近于运行EJB。

    你的问题不在于技术,而在于你的设计。

    具体来说,您正试图通过几个HTTP请求保持事务的活动性。

    当然,大多数常见的习惯用法是,每个请求本身就是一个或多个事务,而不是每个请求都是更大事务的一部分。

    当您在同一讨论中使用术语“无状态”和“事务”时,也存在明显的混淆,因为事务本质上是有状态的。

    您的大问题只是手动管理事务。

    也就是说,简单地说,您获得一个到DB的连接,将其填充到会话中,并确保在事务期间,所有HTTP请求不仅通过同一个会话,而且以实际连接仍然有效的方式通过。具体来说,我不相信有现成的JDBC连接能够在从一台机器到另一台机器的故障切换或负载平衡中存活下来。

    现在,如果长时间运行的事务中有“用户交互”,即启动DB事务并等待用户“做点什么”,那么很简单,这种设计都是错误的。您不想这样做,因为长期存在的事务,特别是在交互环境中,根本就是不好的。就像“穿越小溪”一样糟糕。不要这样做。批处理事务是不同的,但交互的长期事务是不好的。

    您希望使交互式事务尽可能短。

    这本质上意味着您需要提出自己的机制来“提交”数据。

    这样做的一个好方法是,将数据以增量方式构建到单个“事务”文档中,然后将该文档提供给一个“保存”例程,该例程将完成大部分实际工作。例如,您可以在数据库中存储一行,并将其标记为“未保存”。您可以对所有行执行此操作,最后调用一个例程,该例程运行刚刚存储的所有数据,并在单个事务小批量处理中将其标记为“已保存”。

    同时,所有其他SQL“忽略”未“保存”的数据。加上一些时间戳,让reaper进程进行清理(如果你真的想麻烦的话——实际上只在DB中留下死行可能更便宜,这取决于卷大小),这些死行是“未保存”的,因为它们是“未写”事务。

    这并不像听起来那么糟糕。如果你真的想要一个无状态的环境,对我来说就是这样,那么你需要这样做。

    记住,在所有这些方面,持久性技术真的与之无关。问题在于你如何使用你的交易,而不是技术。

        3
  •  3
  •   Binary9    16 年前

    我想你应该看看 apache cayenne

        4
  •  2
  •   David Schmitt    16 年前

    SimpleORM 去年,它的轻巧无魔力设计给我们留下了深刻的印象。现在似乎有一个版本3,但我没有这方面的任何经验。

        5
  •  2
  •   Rob Bygrave    15 年前

    羚羊( http://www.avaje.org

    它是一种更简单、更直观的ORM。

    • 无会话API-无Hibernate会话或JPA实体管理器
    • 延迟加载只是工作
    • 部分对象支持以提高性能
    • 通过“自动提取”自动调整查询
    • Spring集成
    • 非常支持批处理
    • 背景提取
    • DDL生成
    • 如果愿意,可以使用原始SQL(与Ibatis一样好)
    • LGPL牌照

    • 抢劫

        6
  •  1
  •   James Schek    16 年前

        7
  •  1
  •   user1556862    13 年前

    仅供参考,为什么OP的设计是他最大的问题:跨越多个用户请求的事务意味着您在给定的时间内可以拥有与连接到您的应用程序的用户数量相同的打开的事务-事务会使连接保持繁忙,直到提交/回滚。由于同时连接了数千个用户,这可能意味着数千个连接。大多数数据库不支持这一点。

        8
  •  0
  •   Andrej    16 年前

    Hibernate和Toplink(EclipseLink)都不是基于EJB的,它们都是POJO持久性框架(ORM)。

        9
  •  0
  •   Shawn Vader    16 年前

    另一个选择是扭矩,我不是说它比上面提到的任何一个选择都好,而是说它是另一个选择。 它现在已经很旧了,但可能符合您的一些要求。

    Torque

        10
  •  0
  •   Kaitsu    16 年前

    当我自己寻找一个替代者冬眠时,我偶然发现了 DataNucleus Access Platform ,这是一个Apache2许可的ORM。它不仅仅是ORM,因为它还可以在RDBMS以外的其他数据源(如LDAP、DB4O和XML)中提供数据的持久性和检索。我没有任何使用经验,但它看起来很有趣。

        11
  •  0
  •   dacracot    16 年前

    考虑用某种方式彻底打破你的范式 tox . 如果需要Java类,可以将XML结果加载到 JDOM .

    推荐文章