我的开发人员正在发动一场内战。在一个阵营中,他们接受了 Hibernate 和 Spring。在另一个阵营,他们谴责框架——不过他们正在考虑使用 Hibernate。
问题是:新手 Hibernate-Spring 转换者可能会遇到任何令人讨厌的意外、弱点或陷阱吗?
PS:我们有一个不太复杂的 DAO 库。我怀疑它是否具有 Hibernate 的丰富性,但它正在达到某种成熟度(即它在它所包含的最后几个项目中没有改变)。
他们谴责框架?
这太疯狂了。如果您不使用现成的框架,那么您将创建自己的框架。它仍然是一个框架。
我过去曾多次使用过 Hibernate。每次我遇到边缘情况,确定语法会演变为通过文档、谷歌和旧版本进行的寻宝游戏。它是一个强大的工具,但文档记录很差(我最后一次查看)。
至于 Spring,过去几年我面试或看过的几乎所有工作都涉及 Spring,它确实已成为 Java/Web 的事实标准。使用它会帮助您的开发人员在未来更有市场,并且会帮助您,因为您将拥有大量了解您的应用程序的人。
编写自己的框架是诱人的、有教育意义的和有趣的。结果不是很好。
Hibernate 肯定有一些怪癖,但那是因为它试图解决的问题很复杂。每次有人抱怨 Hibernate 时,我都会提醒他们所有无聊的 DAO 代码,如果他们不使用它就必须维护这些代码。
一些提示:
如果你有一个相当复杂的数据库,Hibernate 可能不适合你。在工作中,我们有一个相当复杂的数据库,其中包含大量数据,而 Hibernate 并不适合我们。我们已经开始使用 iBATIS。但是,我知道很多开发商店都成功地使用了 Hibernate——它确实为你做了很多繁重的工作——所以值得考虑。
如果您知道如何正确使用 Spring,那么 Spring 是一个很好的工具。
我会说框架绝对是一件好事——就像其他人指出的那样,你不想重新发明轮子。Spring 包含许多模块,这意味着您不必编写太多代码。不要屈服于“这里没有发明”综合症!
这是我在冬眠时陷入的一件事(我记得)。当您从集合(在父实体中)删除(几个)子对象,然后在一个事务中将新实体添加到同一个集合中而不在中间刷新时,Hibernate 将在“删除”之前执行“插入”。如果子表在其中一个列中具有唯一约束,并且您希望不会违反它,因为您之前已经删除了一些数据(就像我一样),那么准备好感到沮丧。Hibernate 论坛建议:
我不能两者都做,最终调整了 Hibernate 源代码并重新编译。它只有 1 行代码。但是找到一条线的努力相当于大约 27 杯咖啡和 3 个不眠之夜。
这只是您在团队中没有真正专家(专家:对 Hibernate 的理念和内部工作有足够知识的人)使用 Hibernate 时可能最终遇到的问题和怪癖的一个示例。您的问题、解决方案、咖啡升数和不眠夜数可能会有所不同。但你明白了。
延迟加载是使用 Hibernate 作为其持久性框架的 MVC 应用程序中的一大难题。您在控制器中加载对象并将其传递给 JSP 视图。类的部分或全部成员被代理并且一切都爆炸了,因为当控制器完成时您的 Hibernate 会话已关闭。
您需要阅读Open Session in View文章以了解问题并获得解决方案。如果您使用的是 Spring,这篇博客文章描述了 Spring 解决在视图中打开会话的问题。
我在 Java 方面工作不多,但我确实在大量 Java 开发人员中工作过。我的印象是春天还可以。但是每个人都对 Hibernate 感到不安。如果被问到“如果你可以改变一件事,你会改变什么?”,则有一半的团队成员。他们会说“摆脱休眠”。当我开始学习 Hibernate 时,它让我惊讶地发现它的复杂性,但我学得还不够(幸好我已经学会了),无法知道这种复杂性是否合理(也许需要解决一些复杂的问题)。
团队放弃了 Spring 转而支持 Guice,但这更像是一种政治变革,至少从我和与我交谈过的其他开发人员的角度来看是这样。
我一直发现 Hibernate 有点复杂且难以学习。但是随着JPA(Java Persistence API)和EJB(Enterprise Java Beans)3.0 已经存在了一段时间,事情变得容易多了,我更喜欢注释我的类以通过 JavaDoc 或 XML 创建映射。查看Hibernate 中的支持。额外的好处是,如果需要,以后可以(但并非毫不费力地)更改数据库框架。我使用OpenJPA取得了很好的效果。
最近我越来越多地使用JCR (Java Content Repository)。我喜欢我的模块可以共享单个数据存储并且我可以让结构和属性发展的方式。我发现使用节点和属性比将我的对象映射到数据库要容易得多。Jackrabbit是一个很好的实现。
至于 Spring,它有很多我喜欢的特性,但配置所需的 XML 数量意味着我永远不会使用它。相反,我使用Guice并且非常喜欢它。
总结一下,我会向你怀疑的开发人员展示 Hibernate 将如何让他们的生活更轻松。至于 Spring,我会认真检查 Guice 是否是一个可行的替代方案,然后尝试展示 Spring/Guice 如何使开发变得更好、更容易。
我做了很多 Spring/Hibernate 开发。随着时间的推移,人们结合使用两者的方式发生了一些变化。事实证明,原始的 HibernateTemplate 方法难以调试,因为它吞下并包装了其他有用的异常;直接与 Hiberante API 对话!
请继续查看生成的 SQL(配置您的开发日志以显示 SQL)。对数据库有一个抽象层并不意味着您不必再考虑 SQL 了。否则,您将无法获得良好的表现。
考虑项目。在我们有严格的性能要求、复杂的遗留模式或优秀的 DBa 能够编写出色的 SQL 的情况下,我曾多次选择 iBatis 而不是 Hibernate。
我发现使用诸如 Hibernate 之类的知名框架确实很有帮助,因为它使您的代码适合特定的模式或思维方式。这意味着,由于您使用的是 Hibernate,因此您以某种方式编写代码,并且大多数(如果不是所有)了解 Hibernate 的开发人员都能够很容易地遵循您的思路。
当然,这有一个缺点。在成为炙手可热的 Hibernate 开发人员之前,您会发现自己正在尝试将正方形放入圆形孔中。你知道你想做什么,以及在 Hibernate 出现之前你应该怎么做,但是找到 Hibernate 的方法可能需要……相当多的时间。
尽管如此,对于那些经常聘请顾问(他们需要在短时间内理解大量源代码)或者开发人员经常登录和退出的公司,或者您只是不想打赌您的主要开发人员会永远留下来,永远不要换工作——我认为 Hibernate 和其他标准框架是一个不错的主意。
/高手
Spring 和 Hibernate 是难以掌握的框架。当您仍在尝试找出框架时,在截止日期紧迫的项目中使用它们可能不是一个好主意。
框架的好处基本上是尝试提供一个平台以允许一致的代码成为产品。根据经验,建议您让开发人员在框架设置方面有经验,并采用最佳实践。
根据您的应用程序和/或数据库的设计,您还需要规避一些怪癖,以确保框架不会影响性能。
我必须同意关于这一点的许多帖子。我已经在各种环境中广泛使用了这两种方法。如果我可以撤销一个设计决定,那就是使用 Hibernate。实际上,我们在我们的一个产品中预算了一个版本,以将 Hibernate 换成 iBatis 和 Spring-JDBC 以获得世界上最好的方法。我可以让新开发人员更快地使用 Spring-JDBC、Spring-MVC、Spring-Ioc 和 iBatis,而不是让他们使用 Hibernate。
Hibernate 对这个 KISS 开发者来说太复杂了。如果您的 DBA 看到数据库看到的生成的 SQL 并将优化版本发回给您,那么天堂会帮助您休眠。
在我看来,Spring 的最大优势在于它鼓励并支持更好的开发实践,尤其是松耦合、测试和更多接口。没有 Spring 的 Hibernate 可能真的很痛苦,但两者结合起来非常有用。
将现有项目改造到任何框架都会很痛苦,但重构过程通常对长期可维护性有很大好处。
最佳答案提到 Hibernate 的文档记录很差。我同意在线参考手册可以更完整。然而,Hibernate 的作者所写的一本书,《Java persistence with Hibernate》是每个 Hibernate 用户的必读之书,而且非常完整。
框架并不邪恶。甚至 Java SDK 也是一个框架。
他们可能反对的是框架扩散。你不应该把一个框架带到一个项目中去,它应该在合理的时间内带来一致的价值。每个框架都需要一个学习曲线,但以后应该会以更高的生产力和功能来奖励您。
如果您遇到由于不一致的数据库使用、复杂的缓存机制或无数其他原因而难以调试的代码。Hibernate 将增加巨大的价值。除了学习曲线(我花了大约 1 个月的实际工作时间)之外,没有任何陷阱,只要你身边有人为你解释基础知识。
@slim - 今天早上我又和你在一起了。
这听起来像是“这里不发明综合症”的经典案例。如果他们不喜欢 spring,他们应该考虑其他选择,而不是滚动他们自己的框架(无论他们是否承认这样做)。 Guice是一种可能性。还有微微容器。还有其他的,取决于你需要什么。
Spring 和 Hibernate 绝对让生活更轻松。开始使用它们可能会在开始时有点耗时,但稍后您肯定会从中受益。现在 XML 正在被注释取代,您也不需要键入数百行 XML。
您可能需要考虑AppFuse来减少您的学习曲线:生成一个应用程序,研究并调整它,然后就可以开始了。