个性化阅读
专注于IT技术分析

Hibernate几乎毁了我的职业生涯

本文概述

假设你是Java开发人员, 并且即将开始下一个大型项目。你需要做出在项目的其余部分中可以坚持的基本决策。你希望选择灵活数据模型的最佳面向对象抽象, 因为你不想处理纯SQL。你想要支持各种数据, 并且理想情况下, 支持各种数据库。

显而易见的答案是只使用Hibernate, 对吗? 90%的Java开发人员会同意你的观点, 但这是否是正确的决定?

让我们看看如果仅仅因为Hibernate是公认的标准而盲目使用Hibernate会出现什么问题。

考虑一下Java开发人员Monica。最近, 莫妮卡(Monica)被提升为架构师, 现在负责为其公司的新产品布置技术堆栈。她知道在Java世界中, 只有一种好的工具可以处理数据库通信:Hibernate。 Hibernate是众所周知且受支持的JPA标准。但是, 在启动项目之前检查一些事情总是一个好主意。幸运的是, 她的同事Ben认识合适的人。

Hibernate听起来像银弹

4年前

本-莫妮卡你好, 我想向大家介绍约翰。他是Hibernate专家, 将为你提供帮助。

莫妮卡-嗨, 约翰, 很高兴你为我找到了一些时间。因此, 我们正在构建我们的下一个大事。我们正计划成为下一个Facebook或Google。忙碌的日子。这将是巨大的。绝对精彩!大家都很兴奋!我已经晋升为架构师, 所以现在我必须选择我们将要使用的堆栈。唯一缺少的部分是持久性……

约翰-Hibernate!

莫妮卡-是的!究竟!就是我在想的!对于我们来说, 这似乎是一次完美的配对, 而且是真正的交易。为真正的企业问题提供的真正的企业解决方案, 已被市场证明并具有悠久的历史。我听到了很多积极的经验。但是, 我对我们的一位队友有疑问;他完全反对。他对数据库了解很多, 而且他害怕在我们的应用程序和数据库之间添加另一层。他非常聪明, 我需要一些非常好的论据来说服他, 这是一个不错的决定。你能帮我吗?

约翰-当然可以!我会很高兴的。实际上, Hibernate是一种出色的工具。它广泛用于大型真正的企业解决方案, 例如银行。你不会错的。思考持久性:选择Hibernate。如果你使用Java编写, 那么这绝对是正确的选择, 另外你还拥有其他语言的端口。查看需要多少职位描述!

莫妮卡-我绝对同意!我对此有同感。在以前的项目中, 我们主要通过普通的旧JDBC使用SQL。荒谬!我知道!但是, 问题是这样的:团队中有非常聪明的SQL专家, 当他们看到Hibernate生成的SQL时, 他们会感到紧张。它看起来丑陋且难以理解;将来会不会有问题?

约翰-看。 DBA专家有不同的看法。他们担心Hibernate, 因为它似乎取代了他们在项目中的角色。此外, 数据库具有内置的查询优化器, 因此你无需担心这些查询的实际外观。数据库将为你优化它。这一切都是关于快速开发, 而SQL是无法做到的。

莫妮卡-真的吗?不再处理SQL?惊人!上一次, DBA花了数周的时间尝试优化一些查询。周!哦, 告诉你这一点让我感到很尴尬, 但是你是否知道我们正在使用…存储过程(笑)。哦, 真是一团糟。你可以相信该项目仍在使用吗?我为外面的人感到非常抱歉。他们仍然不得不一遍又一遍地编写这个乏味的代码。我想知道它仍然是Java还是SQL项目吗?

John-这正是面向对象方法和关系方法之间的区别。这就是所谓的面向对象的阻抗不匹配。Hibernate可以弥补这一差距。开发人员可以专注于建立业务逻辑。推送功能使利益相关者和整个管理层感到高兴。做最重要的事情:业务!许多样板代码将消失, 你将在逻辑和数据之间建立一个神奇的, 不可见的但可靠的连接。

莫妮卡-相互合作。充分发挥协同作用。就像数据库从一开始就是语言的一部分。我很高兴能成为信仰技术飞跃的领导者。就像软件迷航中的扭曲速度一样。

约翰-是的!知道了!

莫妮卡-天哪, 我好激动!谢谢约翰!我准备好了!

Hibernate

Hibernate不是灵丹妙药。请勿将其视为默认数据库解决方案。

使用非弹性解决方案来增加痛苦

3年前

莫妮卡-嗨, 约翰, 还记得我们去年谈的项目吗?

约翰-好的。怎么样了?

莫妮卡-我们即将投入生产。一切都很好, 但是出现了一些问题。

约翰-当然, 打我。

Monica-好了, 我们不再能够从头开始生成数据库架构。支持架构更改而不丢失数据的最佳方法是什么?

约翰-嗯, 首先, Hibernate并不是要用作生产迁移工具。使用FlywayDB或Liquibase之类的东西。非常简单写下迁移脚本, 然后更新实体模型以及Hibernate映射, 以使其与实际数据库结构保持同步。

莫妮卡-嗯, 我明白了。在上一个项目中, 我们仅使用普通的SQL迁移。

约翰-很好。只要你使实体模型和架构保持同步, 就可以按照自己的喜好进行操作。

莫妮卡-我明白了。还有一件事我们一直在努力解决懒惰/急切的问题。一方面, 我们决定急切地做所有事情, 但似乎次优, 有时, 由于没有会话或诸如此类的操作, 有时无法访问某些字段。那是正常的吗?

John-你需要了解有关Hibernate的更多信息。从数据库进行映射并不简单。基本上, 有多种方法可以做到这一点。你只需要选择一种适合你的方法。延迟获取使你能够按需加载这些对象, 但是你需要在活动会话中进行操作。

Monica-我们仍在为最终部署使用哪个数据库引擎而苦苦挣扎。我以为Hibernate是可移植的, 但是我们有一些使用MS SQL Magic的本机查询, 实际上我们想在生产中使用MySQL。

John-Hibernate为你提供了灵活性, 只要你使用独立标准或HQL;任何本机查询都只会将你的解决方案绑定到数据库。

Monica-好像我们必须坚持使用MS SQL。最后一个问题:我的队友说HQL中没有” limit”关键字。我以为他是在开玩笑, 但我也找不到。很抱歉这个愚蠢的问题……

John-实际上, HQL中没有” limit”关键字。你可以通过查询对象来控制此操作, 因为它是数据库供应商的特定对象。

Monica-似乎所有其他元素都在HQL中很奇怪。没关系。谢谢你的时间!

相关:如何构建多租户应用程序:Hibernate教程

我们现在再次在SQL中共同破解解决方案

2年前

莫妮卡-约翰, 起初我们不会处理SQL, 但是现在看来我们必须这样做。我们的需求在增长, 似乎没有办法解决。感觉不对, 但是我们每天都开始使用SQL。

约翰-嗯, 这没错。你不必在一开始就专注于数据库。但是, 随着项目的发展, 最好使用SQL并进行性能优化。

莫妮卡-有时我们会花几天时间寻找错误。似乎我们必须分析由Hibernate生成的SQL, 因为我们不知道为什么它无法按预期运行并且会产生意外结果。我们遇到了一些在Hibernate Bug Tracker中众所周知的问题。此外, 很难在保持实体模型同步的同时编写适当的迁移信息。这很耗时, 因为我们需要学习很多有关Hibernate内部的知识并预测其工作方式。

约翰-总是有一个学习曲线。你不必写太多, 但是你需要知道它的工作原理。

Monica-使用更大的数据集也很烦人。最近, 我们对数据库进行了大量导入, 但速度非常慢。然后我们发现我们必须清除会话以使其更快。即便如此, 它的运行速度仍然显着降低, 因此我们决定将其重写为纯SQL语句。有趣的是, 编写普通的SQL实际上是最快的方法, 因此我们决定将其作为最后的选择。

约翰-导入不是面向对象的过程。 Hibernate专注于面向对象的设计。请记住, 你始终可以使用本机查询。

Monica-你能帮助我了解Hibernate缓存的工作原理吗?我就是不明白。有一些一级/二级缓存。这是怎么回事?

约翰-好的。这是持久性数据的所谓事务级缓存。可以在逐个类别和逐个收集的基础上配置集群或JVM级缓存。你甚至可以插入集群缓存。但是请记住, 缓存并不知道其他应用程序对持久性存储所做的任何更改。但是, 可以将它们配置为定期删除过期的缓存数据。

莫妮卡-抱歉, 我今天过得很糟糕。你能再解释一下吗?

约翰-好的。每当你通过加载, 获取, 列出, 迭代或滚动传递对象以保存, 更新, saveOrUpdate或检索它时, 该对象就会添加到会话的内部缓存中。你也可以从一级缓存中删除对象及其集合。

莫妮卡-恩…

John-另外, 你可以控制缓存模式。你可以使用普通模式来读取项目并将其写入二级缓存。使用获取模式从第二级读取, 但你不能写回。使用put, 它与get相同, 但是你无法从第二层阅读。你还可以使用刷新模式, 该模式将写入第二级, 但不能从第二级读取并绕过use minimum puts属性, 从而强制刷新从数据库读取的所有项目的第二级缓存。

莫妮卡-我明白了。好。让我考虑一下。哦, 太晚了, 我要走了。谢谢你的时间!

约翰-不用客气!

放弃Hibernate

2个星期前

莫妮卡-约翰, 我以为我们正在进入软件开发的新时代。我以为我们在跳光年。但是, 四年之后, 似乎我们仍在处理所有相同的问题, 只是角度不同。我必须学习Hibernate体系结构, 配置, 日志记录, 命名策略, tuplizer, 实体名称解析器, 增强的标识符生成器, ​​标识符生成器优化, 联合子类, XDoclet标记, 与索引集合的双向关联, 三元关联, idbag, 将隐式多态与其他继承映射, 在两个不同的数据存储之间复制对象, 分离的对象和自动版本控制, 连接释放模式, 无状态会话接口, 集合持久性的分类法, 高速缓存级别, 懒惰或渴望获取等等。即使我所知道的一切, 我们似乎还是失败了。这是软件惨败!最终失败!灾害!大决战!

约翰-等等!发生了什么?

莫妮卡-我们走到了死胡同。我们的应用程序性能太慢了!要获取报告, 我们必须等待两天!为客户实际生成仪表板的两天时间。这意味着每天我们都必须增加计算尾巴, 而仪表板却越来越过时。我们的DBA专家已经工作了两个月来优化一些查询, 而我们的数据库结构却是一团糟。有开发人员支持他, 但是问题是DBA正在考虑使用SQL, 并且开发人员花了很多时间试图将其转换为分离的标准或HQL格式。由于目前的性能至关重要, 因此我们正在尝试尽可能多地使用本机SQL。无论如何, 我们不能做太多事情, 因为数据库架构似乎是错误的。从面向对象的角度来看, 这是正确的, 但是从关系角度来看, 这似乎很可笑。我问自己:这是怎么发生的?开发人员告诉我们, 更改实体结构将是一项巨大的工作, 因此我们负担不起。我记得在上一个项目中那是一团糟, 但我们从未在如此关键的时刻崩溃。我们能够编写一个完全不同的应用程序来处理数据。现在, 修改那些生成的表是有风险的, 因为很难确保实体模型始终能够正常运行。而且这还不是最糟糕的部分!为了提高性能, 我们不仅要解决数据库问题, 还要解决数据库和应用程序之间的整个层的问题。压倒性的!我们有这些新人, 顾问。他们正在尝试提取数据, 将其放入其他存储中, 然后从外部执行计算。这都花了太多时间!

约翰-我不知道该说些什么。

莫妮卡-你看见约翰;我不想怪你我选择了Hibernate来解决所有这些问题, 但是现在我知道这不是灵丹妙药。损坏已经造成, 并且是不可逆的。实际上, 我想问你一个问题:我在职业生涯的最后四年中一直在处理Hibernate的东西。看来我目前的公司没有前途。你能帮助我吗?

那么, 我们学到了什么?

今天

约翰-嘿, 彼得, 让我介绍一下莫妮卡。

彼得-嗨, 莫妮卡!我们正在构建你知道的下一个新的重大事件。这将是巨大的!我们想成为Uber!你知道持久性吗?

莫妮卡-不Hibernate!

本文总结

Monica是Hibernate专家。但是, 在这种情况下, Hibernate是一个错误的决定。当她发现自己的解决方案比原来的问题变得更大时, 这是整个项目的最大威胁。

数据是应用程序的主要目的, 无论是否影响数据, 它都会影响整个体系结构。正如我们从该故事中学到的, 不要仅仅因为你的Java应用程序正在使用数据库或出于社会证明而使用Hibernate。选择一个包含灵活性的解决方案。健壮的JDBC包装器有很多选项, 例如JdbcTemplate或Fluent JDBC Wrapper。另外, 还有其他强大的解决方案, 例如jOOQ。

赞(0)
未经允许不得转载:srcmini » Hibernate几乎毁了我的职业生涯

评论 抢沙发

评论前必须登录!