我不确定是否有更好的方法在Java中开发数据库支持的应用程序,但我想我会问。
我非常喜欢Hibernate,但也有很多问题。当你拥有和我一样多的经验时,他们中的大多数并不是那么重要,但我认为我遇到的最大问题是一个适合所有延迟加载模型。绝对讨厌它 - 那里必须有更好的东西......不是吗?
我讨厌延迟加载模型的原因是,虽然在配置文件中指定延迟和非延迟是很方便的,但是应用程序的许多部分更喜欢在一个区域中进行延迟加载而不是延迟加载在另一个。如果你想要满足程序的两个部分,你需要忍受延迟加载并手动加载实体及其子代......以及他们的孩子......等等。这只是膨胀,无法解决真正的编程问题 - 比如完成项目的功能。
你想要使用的加载策略似乎应该独立于映射信息,但是除了在java代码中编写加载之外,这对hibernate来说是不可能的(据我所知)。
我对延迟加载的另一个问题是,当你遇到问题时,它不容易预测。在将应用程序部署到Tomcat之前,我经常不会发现lazyloadexceptions。
当这些异常发生在框架中时,感觉更加臃肿 - 就像杰克逊调用尚未加载的集合一样。或者Spring可能正在访问我从未问过的属性,所以无论如何都会抛出一个LazyInitializationException - 除了他们的框架触及我所有的bean属性之外没有任何理由。
无论如何,因为我在集成测试期间无法发现这些问题...当我在Tomcat中发现它们时,我经常要关闭tomcat,进行更改,重新编译,重新加载tomcat,重新登录到我的应用程序,返回到我正在看的页面,看它是否已修复 - 这确实是一个巨大的痛苦。修复其中一个错误需要很长时间。我觉得这只是妨碍了我实际做的事情。
最后,我觉得这样的细节真的让我失望。当我看着我的日子并问:“我今天生产了什么?” - 我发现这样的问题确实让我觉得我感觉自己已经完成了某些事情。
当然,我可以关闭延迟加载......但是后来我的表现非常糟糕。
有更好的方法吗? “只是做正确的事”,表现得很好,更容易推理?
由于
答案 0 :(得分:3)
首先,这与Hibernate无关。几乎任何ORM(当然任何JPA提供程序)都以类似的方式实现延迟加载。
至于“更喜欢在一个区域中进行延迟加载而在另一个区域中没有延迟加载”,如果您正在使用查询,则可以通过HQL fetch join覆盖延迟提取。对于直线上升session.get()
,通常没有必要这样做(注意 - 见下文),你可以让延迟加载为你做出魔力。要实现这一点,您需要确保您的会话保持活动状态,直到完成对实体的所有请求(其属性/集合/等...),这通常通过Open Session in View pattern实现。
Spring也有corresponding interceptor。
注意:您必须加载所有实体的依赖关系的一种情况是您要将其发送到远程系统(从而使原始会话不可用)。这通常由marshaller处理。
答案 1 :(得分:3)
我同意其他人认为更好的概念是主观的和依赖于上下文的。 JPA / Hibernate的真正替代品是:
它是Java中最流行的SQL模板引擎。它将SQL语句外部化为XML文件,可以通过ID或其他方式从中加载它们。作为模板引擎,MyBatis还支持SQL组合和用于循环和分支语句的简洁模板语言。
这是一种流行的SQL DSL,允许直接在Java中进行SQL语句的类型安全构造。与MyBatis不同,这个库鼓励在Java中嵌入SQL,而不是将其外化。 (免责声明,我为供应商工作)
...包括以SQL字符串为中心的库,可以减轻直接使用JDBC时的一些痛苦:
答案 2 :(得分:2)
Hibernate和其他ORM旨在使RDBMS与面向对象的应用程序一起工作。如果您不被迫使用RDBMS,我只需使用ODBMS。
许多ODBMS通过字节码增强支持隐式延迟加载,因此编写访问未正确加载的对象的代码几乎是不可能的。您通常也可以指定(每个代码路径)闭包,这些闭包不是逐个加载对象,而是批量加载,这样可以提高性能。
一些ODBMS是:
答案 3 :(得分:1)
我不知道“比Hibernate更好”,但是如果你不喜欢它,还有其他的选择:
答案 4 :(得分:1)
要考虑的另一个ORM库是www.sormula.org。它支持关系,但延迟加载是可选的。它旨在成为复杂ORM解决方案世界的简单替代品。我是作者。
答案 5 :(得分:0)
一个人已经在视图中提到了Open Session,这将消除大部分(如果不是全部)延迟加载问题(但它带来了自己的问题)。
Open JPA有一个叫做“fetch groups”的东西。这基本上是一组命名的提取设置,您可以在运行查询之前设置它们等。然后在运行查询之前选择适当的提取策略(可能在您的服务impl中)。这样,获取计划与映射是分开的。您可以根据用例配置任意数量的提取计划。在一个获取计划中,一个特定的关联是懒惰的,但在另一个,它是渴望/ JOIN。看起来很棒。
如果您已经编写了JPA规范而不是本机Hibernate,那么切换到Open JPA可能很容易。
如果我没弄错的话,正在做一些工作来实现Hibernate中的获取组,但我现在懒得谷歌。
答案 6 :(得分:0)
一些经典的ODBMS也实现了JPA标准 Versant。所以很容易尝试一下。如果你想知道他们有多快查看Polepos Benchmark,它将不同的持久性API与不同的实现与不同的RDBMS / ODBMS进行比较。您还可以使用自己的用例轻松扩展基准测试,并使用所有不同的持久性技术运行它们。