Hibernate或TopLink的替代品?

时间:2009-01-05 13:44:56

标签: java hibernate jpa java-ee eclipselink

Hibernate是否有可行的替代方案?优选不以JPA为基础的东西。

我们的问题是我们正在构建一个复杂的(如同许多对象相互引用)有状态的RIA系统。似乎Hibernate主要用于一次性应用程序 - JSF等。

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

除了我可怜的解释之外,最重要的是Hibernate做了我们不喜欢的魔术。看起来TopLink并没有更好,它也是在EJB之上编写的。

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

有什么想法,或者我要求的东西不存在?

编辑:我很抱歉我的模糊术语,并感谢大家的更正和有见地的答案。那些纠正我的人,你们都是正确的,我的意思是JPA,而不是EJB。

11 个答案:

答案 0 :(得分: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()),这可能会出现问题。

答案 1 :(得分:6)

如上所述,JPA<> EJB,它们甚至都不相关。 EJB 3恰好利用JPA,但就是这样。我们有很多使用JP​​A的东西,甚至没有接近运行EJB。

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

或者,我应该说,你的设计并不适合任何现代框架。

具体来说,您正在尝试通过多个HTTP请求保持事务处于活动状态。

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

当你在同一个讨论中使用“无国籍”和“交易”一词时,也存在明显的混淆,因为交易具有固有的状态。

您唯一的问题就是手动管理您的交易。

如果您的事务发生在多个HTTP请求上,并且这些HTTP请求碰巧正在“非常快”地运行,一个接一个地运行,那么您不应该真正遇到任何实际问题,除非您必须确保您的HTTP请求正在使用相同的数据库连接,以便利用数据库事务工具。

也就是说,简单来说,您可以获得与数据库的连接,将其填充到会话中,并确保在事务持续期间,所有HTTP请求不仅会通过相同的会话,而且会在这样一种方式,实际连接仍然有效。具体来说,我不相信有一个现成的JDBC连接,它实际上可以在故障转移或从一台机器到另一台机器之间实现负载均衡。

因此,简单地说,如果要使用数据库事务,则需要确保使用相同的数据库连接。

现在,如果你的长期运行事务中有“用户交互”,即你启动数据库事务并等待用户“做某事”,那么,很简单,这种设计都是错误的。你不想这样做,因为长期交易,特别是在交互式环境中,只是简单的坏。就像“穿越溪流”一样糟糕。不要这样做。批处理事务是不同的,但交互式长期事务处理是错误的。

您希望保持交互式交易尽可能短暂。

现在,如果你不能确保你能够为你的交易使用相同的数据库连接,那么,恭喜你,你可以实现自己的交易。这意味着您可以设计系统和数据流,就好像后端没有事务处理功能一样。

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

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

同时,所有其他SQL“忽略”未“保存”的数据。抛出一些时间戳,并有一个收割机进程清理(如果你真的想要打扰 - 实际上可能更容易在数据库中留下死行,取决于数量),这些死的“未保存”行,因为这些是“未经注册的”交易。

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

介意,在所有这些中,持久性技术实际上与它无关。问题是你如何使用你的交易,而不是技术。

答案 2 :(得分:3)

我认为你应该看看apache cayenne,它是“大”框架的一个非常好的替代品。凭借其体面的建模者,通过良好的文档缩短了学习曲线。

答案 3 :(得分:2)

我去年看过SimpleORM,其轻巧的无魔法设计给我留下了深刻的印象。现在似乎有一个版本3,但我没有任何经验。

答案 4 :(得分:2)

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

使用它是一种更简单,更直观的ORM。

  • 使用JPA注释进行映射(@ Entity,@ OneToMany等)
  • 无会话API - 无Hibernate会话或JPA实体管理器
  • 延迟加载正常工作
  • 部分对象支持以提高性能
  • 通过“Autofetch”进行自动查询调整
  • Spring Integration
  • 大量查询支持
  • 对批处理的大力支持
  • 背景提取
  • DDL Generation
  • 如果您愿意,可以使用原始SQL(和Ibatis一样)
  • LGPL许可证

  • 罗布。

答案 5 :(得分:1)

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

尽管如此,根据您的描述,Toplink应该能够解决您的问题。大多数情况下,听起来你需要能够在请求开始和结束时从持久层中附加/分离对象。

答案 6 :(得分:1)

仅供参考,为什么OP的设计是他最大的问题:跨多个用户请求跨越事务意味着您可以在给定时间拥有尽可能多的打开事务,因为有用户连接到您的应用程序 - 事务保持连接忙它被提交/回滚。有数千个同时连接的用户,这可能意味着成千上万的连接。大多数数据库都不支持此功能。

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

另一个选择是Torque,我并不是说它比上面提到的任何选项更好,但只是它是另一种选择。 它现在变得很老了,但可能符合你的一些要求。

Torque

答案 9 :(得分:0)

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

答案 10 :(得分:0)

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