Как Hibernate чуть не разрушил мою карьеру

Опубликовано: 2022-03-11

Представьте, что вы разработчик Java и собираетесь начать свой следующий большой проект. Вам нужно принять фундаментальные решения, которые останутся с вами до конца проекта. Вы хотите выбрать наилучшую объектно-ориентированную абстракцию своей гибкой модели данных, поскольку не хотите иметь дело с простым SQL. Вы хотите поддерживать все виды данных и, в идеале, поддерживать все типы баз данных.

Очевидный ответ — просто использовать Hibernate , верно? 90% Java-разработчиков согласятся с вами, но делает ли это решение правильным?

Давайте посмотрим, что может пойти не так, если вы слепо используете Hibernate только потому, что это общепринятый стандарт.

Рассмотрим Монику, разработчика Java. Монику недавно повысили до должности архитектора, и теперь она отвечает за разработку стека технологий для нового продукта в своей компании. Она знает, что в мире Java есть только один хороший инструмент для взаимодействия с базой данных: Hibernate . Hibernate — хорошо известный и поддерживаемый стандарт JPA. Тем не менее, всегда полезно проверить несколько вещей перед началом проекта. К счастью, ее коллега Бен знает нужного парня.

Спящий режим звучит как серебряная пуля

4 года назад

Бен – Привет, Моника, я хотел бы представить Джона. Он эксперт по Hibernate , и он поможет вам.

Моника – Эй, Джон, рад, что ты нашел для меня время. Итак, вы знаете, мы строим нашу следующую большую вещь. Мы планируем стать следующим Facebook или Google. Напряженные дни. Это будет грандиозно. Абсолютно фантастично! Все так взволнованы! Меня повысили до роли архитектора, так что теперь мне нужно выбрать стек, который мы будем использовать. Не хватает только настойчивости…

Джон - Спи !

Моника - Да! Точно! Как раз то, что я думал! Это похоже на идеальное совпадение и реальную сделку для нас. Настоящее корпоративное решение для реальной корпоративной проблемы, проверенное рынком и имеющее долгую историю. Я слышал так много положительного опыта с ним. Однако у меня есть проблема с одним из наших товарищей по команде; он категорически против. Он много знает о базах данных и боится добавить еще один слой между нашим приложением и базой данных. Он очень умен, и мне нужны действительно веские аргументы, чтобы убедить его, что это правильное решение. Вы можете помочь мне с этим?

Джон – Конечно! буду рад. Hibernate — действительно выдающийся инструмент. Он широко используется в крупных, настоящих корпоративных решениях, таких как банки. Вы не ошибетесь. Подумайте о настойчивости: выберите Hibernate . Если вы пишете на Java, это абсолютно правильный выбор, плюс у вас есть порты для других языков. Посмотрите, сколько описаний должностей требует этого!

Моника - Абсолютно согласна! У меня такие же чувства по этому поводу. В предыдущем проекте мы использовали в основном SQL через старый добрый JDBC. Нелепый! Я знаю! Но вот в чем дело: у нас в команде есть очень умные ребята из SQL, и когда они увидели SQL, сгенерированный Hibernate , они занервничали. Это казалось уродливым и нечитаемым; не будет ли это проблемой в будущем?

Джон – Смотри. Ребята из DBA придерживаются другой точки зрения. Они боятся Hibernate , потому что он как бы заменяет их роль в проекте. Кроме того, базы данных имеют встроенные оптимизаторы запросов, поэтому вам не нужно беспокоиться о том, как эти запросы будут выглядеть на самом деле. База данных оптимизирует его для вас. Все дело в быстрой разработке, чего SQL не может.

Моника – Правда?! Больше не имеете дело с SQL? Удивительно! В прошлый раз администратор баз данных потратил недели, пытаясь оптимизировать некоторые запросы. Недели! О, мне так неловко вам это говорить, но знаете ли вы, что мы использовали… хранимые процедуры (смеется). О, это был такой беспорядок. Можете ли вы поверить, что проект все еще использует его? Мне так жаль людей там. Им все еще приходится писать этот утомительный код снова и снова. Интересно, это все еще проект Java или SQL?

Джон – В этом и заключается разница между объектно-ориентированным подходом и реляционным. Это так называемое объектно-ориентированное несоответствие импеданса. Спящий режим может закрыть этот пробел. Разработчики могут сосредоточиться на построении бизнес-логики. Push-функции делают заинтересованные стороны и все руководство счастливыми. Делайте то, что важнее всего: Бизнес! Много шаблонного кода исчезнет, ​​и у вас появится волшебная, невидимая, но надежная связь между логикой и данными.

Моника - Взаимное сотрудничество. Полная синергия. Как будто база данных была частью языка с самого начала. Я так счастлив, что стал лидером этого технологического прыжка веры. Это похоже на скорость деформации в программном путешествии.

Джон - Ага! У тебя вышло!

Моника – О боже, я так взволнована! Спасибо, Джон! Я готов!

Hibernate не панацея. Не рассматривайте его как решение для базы данных по умолчанию.
Твитнуть

Проблемы роста с негибкими решениями

3 года назад

Моника – Эй, Джон, помнишь проект, о котором мы говорили в прошлом году?

Джон – Конечно. Как идут дела?

Моника – Мы скоро приступим к съемкам. Все хорошо, но возникли некоторые вопросы.

Джон – Конечно, ударь меня.

Моника – Что ж, мы больше не можем генерировать схему нашей базы данных с нуля. Как лучше всего поддерживать изменения схемы без потери данных?

Джон – Ну, во-первых, Hibernate не предназначен для использования в качестве инструмента для переноса рабочей среды. Используйте что-то вроде FlywayDB или Liquibase. Это довольно просто. Вы записываете сценарии миграции, затем обновляете модель объекта вместе с сопоставлениями Hibernate , чтобы она синхронизировалась с фактической структурой базы данных.

Моника – Хм, понятно. В предыдущем проекте мы использовали простую миграцию SQL.

Джон – Тоже хорошо. Пока вы синхронизируете модель объекта и схему, делайте это так, как вам нравится.

Моника - Я вижу. Есть еще одна вещь. Мы всегда боремся с проблемами ленивой/нетерпеливой выборки. В какой-то момент мы решили сделать все на скорую руку, но это кажется неоптимальным, к тому же иногда не получается получить доступ к некоторым полям из-за отсутствия сессии или чего-то в этом роде. Это нормально?

Джон — Вам нужно больше узнать о Hibernate . Отображение из базы данных не является простым. В принципе, есть несколько способов сделать это. Вам просто нужно выбрать способ, который работает для вас. Ленивая выборка дает вам возможность загружать эти объекты по запросу, но вам нужно работать в рамках активного сеанса.

Моника . Мы все еще пытаемся решить, какой механизм базы данных использовать для окончательного развертывания. Я думал, что Hibernate является переносимым, но у нас есть несколько нативных запросов, использующих магию MS SQL, и мы действительно хотели бы использовать MySQL в производстве.

ДжонHibernate дает вам гибкость, если вы используете отдельные критерии или HQL; любые собственные запросы просто привяжут ваше решение к базе данных.

Моника – Похоже, тогда мы должны придерживаться MS SQL. Последний вопрос: мой товарищ по команде сказал, что в HQL нет ключевого слова «лимит». Я думал, что он шутит, но тоже не нашел. Извините за глупый вопрос…

Джон . Действительно, в HQL нет ключевого слова limit. Вы можете управлять этим с помощью объекта запроса, поскольку он зависит от поставщика базы данных.

Моника : Странно, что все остальные элементы в HQL. Неважно. Спасибо за ваше время!

Связанный: Как создать многопользовательское приложение: Учебное пособие по Hibernate

Теперь мы снова вместе разрабатываем решения на SQL

2 года назад

Моника – Джон, вначале мы не собирались заниматься SQL, но теперь, похоже, придется. Наши потребности растут, и кажется, что нет никакого способа обойти это. Это кажется неправильным, но мы снова начали ежедневно использовать SQL.

Джон – Что ж, это не так. Вам не нужно было фокусироваться на базе данных в самом начале. Однако по мере роста проекта полезно использовать SQL и работать над оптимизацией производительности.

Моника – Иногда мы целыми днями ищем ошибки. Похоже, нам нужно проанализировать сгенерированный Hibernate SQL, потому что мы понятия не имеем, почему он не работает должным образом и дает неожиданные результаты. Мы столкнулись с некоторыми проблемами, которые хорошо известны в системе отслеживания ошибок Hibernate . Кроме того, сложно написать правильные миграции, сохраняя синхронизацию модели объекта. Это отнимает много времени, так как нам нужно много узнать о внутренностях Hibernate и предсказать, как он будет работать.

Джон – Всегда нужно учиться. Вам не нужно много писать, но вам нужно знать, как это работает.

Моника : работа с большими наборами данных тоже раздражает. Недавно мы сделали массивный импорт в базу данных, и он был мучительно медленным. Затем мы обнаружили, что нам нужно очистить сеанс, чтобы сделать его быстрее. Несмотря на это, он все еще значительно медленнее, поэтому мы решили переписать его в виде простых операторов SQL. Что забавно, так это то, что написание простого SQL было на самом деле самым быстрым способом сделать это, поэтому мы решили сделать это в качестве последнего варианта.

Джон – Импорт не является объектно-ориентированным процессом. Hibernate фокусируется на объектно-ориентированном дизайне. Помните, что вы всегда можете использовать нативные запросы.

Моника. Не могли бы вы помочь мне понять, как работает кэш Hibernate ? Я просто не понимаю. Есть несколько кешей первого/второго уровня. О чем это все?

Джон – Конечно. Это так называемый кэш постоянных данных на уровне транзакций. Кэш уровня кластера или JVM можно настроить для каждого класса и коллекции за коллекцией. Вы даже можете подключить кластерный кеш. Но помните, что кеши не знают об изменениях, внесенных в постоянное хранилище другим приложением. Однако их можно настроить на регулярное удаление просроченных кэшированных данных.

Моника – Извини, думаю, у меня плохой день. Можете ли вы объяснить это немного больше?

Джон – Конечно. Всякий раз, когда вы передаете объект в save , update , saveOrUpdate или извлекаете его с помощью load , get , list , iterate или scroll , этот объект добавляется во внутренний кэш сеанса. Вы также можете удалить объект и его коллекции из кеша первого уровня.

Моника - Эээ...

Джон - Кроме того, вы можете управлять режимами кеша. Вы можете использовать normal режим для чтения и записи элементов в кэш второго уровня. Используйте режим get для чтения со второго уровня, но вы не можете писать обратно. Используйте put , то же самое, что и get , но вы не можете читать со второго уровня. Вы также можете использовать режим refresh , который будет записывать на второй уровень, но не читать из него, и обходить свойство use minimal puts , принудительно обновляя кэш второго уровня для всех элементов, считанных из базы данных.

Моника - Я вижу. Ok. Позвольте мне подумать об этом. О, уже поздно, мне нужно идти. Спасибо за ваше время!

Джон – Пожалуйста!

Отказ от спящего режима

2 недели назад

Моника – Джон, я думала, мы вступаем в новую эру разработки программного обеспечения. Я думал, мы совершаем прыжок на световой год. Но по прошествии четырех лет кажется, что мы все еще решаем все те же проблемы, только под другим углом. Мне пришлось изучить архитектуру Hibernate , конфигурацию, ведение журнала, стратегии именования, туплизаторы, преобразователи имен сущностей, улучшенные генераторы идентификаторов, оптимизацию генераторов идентификаторов, объединение-подклассы, разметку XDoclet, двунаправленные ассоциации с индексированными коллекциями, тернарные ассоциации, idbag, смешивание неявного полиморфизма с другие сопоставления наследования, репликация объекта между двумя разными хранилищами данных, отсоединенные объекты и автоматическое управление версиями, режимы освобождения соединения, интерфейс сеанса без сохранения состояния, таксономия сохранения коллекции, уровни кэша, ленивая или активная выборка и многое, многое другое. Даже со всем, что я знаю, кажется, что мы сильно потерпели неудачу. Это фиаско программного обеспечения! Полный провал! Катастрофа! Армагеддон!

Джон – Подожди! Что случилось?

Моника – Мы зашли в тупик. Производительность нашего приложения смехотворно низкая! Чтобы получить отчет, мы должны ждать два дня! Два дня, чтобы фактически сгенерировать информационную панель для клиента. Это означает, что каждый день нам приходится наращивать хвост вычислений, а наш дашборд все больше и больше устаревает. Наш эксперт DBA уже два месяца работает над оптимизацией некоторых запросов, а структура нашей базы данных в полном беспорядке. Есть разработчики, поддерживающие его, но проблема в том, что администратор базы данных думает на языке SQL, и разработчики тратят дни, пытаясь перевести это в отдельные критерии или формат HQL. Мы пытаемся максимально использовать нативный SQL, поскольку на данный момент производительность имеет решающее значение. В любом случае, мы мало что можем сделать, так как схема базы данных кажется неправильной. Это кажется правильным с точки зрения объектно-ориентированного подхода, но кажется нелепым с реляционной точки зрения. Я спрашиваю себя: как это произошло? Разработчики говорят нам, что изменение структуры сущностей потребует огромных усилий, поэтому мы не можем себе этого позволить. Помню, в предыдущем проекте был бардак, но мы никогда не оказывались в такой критической точке. Мы смогли написать совершенно другое приложение для работы с данными. Теперь изменять эти сгенерированные таблицы рискованно, поскольку очень сложно убедиться, что модель объекта всегда будет вести себя правильно. И это еще не самое худшее! Чтобы повысить производительность, мы должны решить не только проблемы с базой данных, но и проблемы со всем слоем между нашей базой данных и приложением. Это потрясающе! У нас есть эти новые ребята, вы знаете, консультанты. Они пытаются извлечь данные, поместить их в какое-то другое хранилище, а затем выполнять вычисления извне. Все это занимает слишком много времени!

Джон – Я не знаю, что сказать.

Моника – Ты видишь Джона; Я не хочу винить тебя. Я выбрал Hibernate для решения всех этих проблем, но теперь я узнал, что это не панацея. Ущерб нанесен, и он необратим. На самом деле, я хотел бы спросить вас кое о чем: последние четыре года своей карьеры я занимался Hibernate . Кажется, у меня нет будущего в моей нынешней компании. Вы можете помочь мне?

Итак, какой урок мы извлекли?

Сегодня

Джон – Привет, Питер, позвольте представить Монику.

Питер – Привет, Моника! Вы знаете, мы строим нашу новую следующую большую вещь. Он будет огромным! Мы хотим быть как Uber! Знаете ли вы, может быть, как настойчивость…

Моника - Не впадай в спячку !

Заворачивать

Моника — эксперт по Hibernate . Однако Hibernate в данном случае был неправильным решением. В тот момент, когда она обнаружила, что ее решение превратилось в большую проблему, чем оригинал, это стало самой большой угрозой для всего проекта.

Данные являются центральной целью приложения и, нравится вам это или нет, влияют на всю архитектуру. Как мы узнали из истории, не используйте Hibernate только потому, что ваше Java-приложение использует базу данных или из-за социального доказательства. Выберите решение, обеспечивающее гибкость. Существует множество вариантов надежных оболочек JDBC, таких как JdbcTemplate или Fluent JDBC Wrapper. Кроме того, есть другие мощные решения, такие как jOOQ.