Hibernate或TopLink的替代方案?

6
有没有Hibernate的替代方案?最好不要基于JPA。
我们的问题是,我们正在构建一个复杂的(也就是很多对象彼此引用)有状态的RIA系统。似乎Hibernate主要设计用于一次性应用程序 - JSF等等。
问题主要在于延迟加载。由于在初始化和实际加载延迟集合之间可能会有几个HTTP请求,因此每次事务都使用一个会话是行不通的。长期会话(每个应用程序一个)也不起作用,因为一旦交易遇到问题并抛出异常,整个会话将无效,从而使延迟加载的对象无法使用。然后,还有各种各样的东西对我们不起作用(例如来自已初始化的事务外部的数据隐式持久化)。
撇开我的糟糕解释不谈,归根结底,Hibernate做了我们不喜欢的魔术。似乎TopLink也不见得更好,它也是基于EJB编写的。
因此,我们最需要的是一个无状态的持久层(甚至是足够聪明的面向对象数据库抽象层)。
有什么想法,或者我正在寻找不存在的东西吗?
编辑:对于我的模糊术语表示歉意,并感谢您们纠正和有见地的答案。那些纠正我的人,你们都是正确的,我所说的是JPA,而不是EJB。

你的编程范式必须是ORM吗? - dacracot
11个回答

7

如果您需要另一个JPA提供程序(Hibernate是其中之一),那么请查看EclipseLink。它比TopLink Essentials的JPA 1.0参考实现功能更完整。事实上,EclipseLink将是Glassfish V3 Final附带的JPA 2.0参考实现。

JPA很好,因为您可以在容器内外都使用它。我编写了使用JPA的Swing客户端,并取得了良好的效果。它没有与EJB 2.0 / 2.1相同的污名和XML负担。

如果您需要更轻量级的解决方案,请查看ibatis, 我认为它是Java平台上我首选的持久化技术。它很轻便,依赖于SQL(ORM用户花费多少时间来尝试使其ORM产生良好的SQL真是令人惊讶),并且做到了JPA的90-95%(如果您想要延迟加载相关实体)。

只是纠正一些观点:

  • JPA是EJB的持久层,而不是建立在EJB之上的;
  • 任何一个合格的JPA提供者都有大量的缓存机制,很难搞清楚所有细节(这是"为什么简单事情变得如此复杂"的好例子)。除非你做了一些未说明的事情,否则异常不应该对你的托管对象造成影响。运行时异常通常会回滚事务(如果使用Spring的事务管理,谁不会呢?)。提供者将维护已加载或持久化对象的缓存副本。如果您想在实体管理器之外进行更新,则可能会出现问题(需要显式缓存刷新或使用EntityManager.refresh())。

6
如上所述,JPA并不等同于EJB,它们甚至没有关联。EJB 3碰巧利用了JPA,但仅限于此。我们有许多使用JPA的东西,与运行EJB毫不相干。
你的问题不在技术方面,而在于你的设计。
或者说,你的设计几乎不适合任何现代框架。
具体来说,你试图在多个HTTP请求之间保持事务活动。
自然而然地,每个常见的习语都是每个请求本身都是一个或多个事务,而不是每个请求都是大事务的一部分。
当你在同一讨论中使用“无状态”和“事务”这个词汇时,也会存在明显的混淆,因为事务本质上是具有状态的。
你的主要问题在于手动管理事务。
如果你的事务在多个HTTP请求中发生,并且这些HTTP请求恰好相继快速运行,则你实际上不应该遇到任何实际问题,除非你必须确保你的HTTP请求使用相同的DB连接以利用数据库的事务功能。
也就是说,简单来说,你需要获取到DB连接,在会话中存储它,并确保在事务期间,所有的HTTP请求都通过同一个会话进行,而且连接实际上仍然有效。具体而言,我不认为有一个现成的JDBC连接能够从一个机器进行故障转移或负载平衡。
因此,简单地说,如果你想使用DB事务,你需要确保使用相同的DB连接。
现在,如果你的长时间运行的事务中有“用户交互”,例如,你开始DB事务,并等待用户“做某些事情”,那么,简单地说,该设计就是错误的。在交互式环境中,长时间运行的事务,尤其是具有用户交互的事务,是非常糟糕的。像“Crossing The Streams”这样糟糕。不要这样做。批处理事务是不同的,但是交互式的长时间运行的事务是不好的。
你需要使你的交互式事务尽可能短暂。
现在,如果你不能确保能够为你的事务使用相同的DB连接,那么恭喜你,你需要实现自己的事务。这意味着你需要设计你的系统和数据流程,就好像后端没有任何事务能力一样。
这基本上意味着你需要想出自己的机制来“提交”你的数据。
一个很好的方法是逐步构建你的数据,形成单个的“事务”文档,然后将该文档提供给执行大部分真正工作的“保存”例程。例如,你可以将一行存储在数据库中,并将其标记为“未保存”。你对所有行都这样做,最后调用一个例程,运行通过你刚刚存储的所有数据,并以单个事务小批量过程将其全部标记为“已保存”。
同时,您的其他SQL语句会“忽略”未“保存”的数据。如果加入一些时间戳并启用收割进程(如果您真的想要打扰——可能更便宜的方法是将死行保留在数据库中,这取决于数量),则可以清除这些“未保存”的死行,因为这些是“未提交”的事务。
这并没有听起来那么糟糕。如果您真的想要一个无状态环境,这正是我所想的,那么您需要像这样做一些事情。
请注意,在所有这些中,持久化技术实际上与此无关。问题在于如何使用事务,而不是技术本身。

感谢您的评论。很抱歉我的术语表述不够清晰,但是您已经准确地指出了我们的问题所在。这正是我们团队目前正在做的事情。我只是希望能有更简单的方法... - Henrik Paul

3

我认为你应该看看Apache Cayenne,它是一个非常好的替代“大型”框架的选择。有了它体面的建模工具,通过良好的文档学习曲线可以缩短。


2

Ebean ORM (http://www.avaje.org)

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

  • 使用JPA注解进行映射(@Entity, @OneToMany等)
  • 无需Hibernate Session或JPA Entity Manager的无会话API
  • 懒加载可正常运行
  • 支持部分对象以提高性能
  • 通过“Autofetch”自动查询调优
  • 与Spring集成
  • 支持大查询
  • 批处理支持很棒
  • 后台获取
  • DDL生成
  • 喜欢的话也可以使用原始SQL(和Ibatis一样好用)
  • LGPL许可证

  • Rob.


2

去年我看过SimpleORM,并且对它的轻量级无魔法设计印象深刻。现在似乎有第三个版本,但我没有使用过。


1
仅供参考,为什么OP的设计是他最大的问题:跨越多个用户请求的事务意味着您可以在任何时候拥有与连接到您的应用程序的用户数量相同的打开事务数 - 事务会使连接保持繁忙状态,直到提交/回滚。对于同时连接的成千上万个用户,这可能意味着成千上万个连接。大多数数据库不支持此功能。

1

BEA Kodo(前身为Solarmetric Kodo)是另一种选择。它支持JPA、JDO和EJ3。它高度可配置,可以支持积极的预取、对象分离/附加等。

尽管从您所描述的情况来看,Toplink应该能够处理您的问题。大多数情况下,听起来像是您需要能够在请求开始和结束时从持久层中附加/分离对象。


0
当我正在寻找Hibernate的替代品时,我偶然发现了DataNucleus Access Platform,这是一个基于Apache2许可证的ORM。它不仅仅是ORM,还可以在其他数据源(如LDAP、DB4O和XML)中提供数据的持久性和检索。虽然我没有使用过,但看起来很有意思。

0

考虑使用像tox这样的东西完全打破你的范式。如果你需要Java类,你可以将XML结果加载到JDOM中。


0

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

我同意之前的回答:iBatis是ORM框架的一个很好的替代品:具有对SQL的完全控制,并带有良好的缓存机制。


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