Можно ли запускать приложения Hibernate, настроенные hbm2ddl.auto=update
для обновления схемы базы данных, в производственной среде?
Можно ли запускать приложения Hibernate, настроенные hbm2ddl.auto=update
для обновления схемы базы данных, в производственной среде?
Ответы:
Нет, это небезопасно.
Несмотря на все усилия команды Hibernate, вы просто не можете полагаться на автоматические обновления в работе . Напишите свои собственные патчи, просмотрите их с помощью администратора баз данных, протестируйте их, а затем примените их вручную.
Теоретически, если обновление hbm2ddl работало в разработке, оно должно работать и в производстве. Но на самом деле это не всегда так.
Даже если это работает хорошо, это может быть неоптимальным. АБД платят так много по причине.
Мы делаем это в производстве, хотя с приложением, которое не является критически важным, и без высокооплачиваемых администраторов баз данных. Это всего лишь один менее ручной процесс, который подвержен человеческим ошибкам - приложение может обнаружить разницу и делать правильные вещи, плюс вы предположительно протестировали ее в различных средах разработки и тестирования.
Одно предостережение - в кластерной среде вы можете избежать этого, потому что одновременно могут появляться несколько приложений и пытаться изменить схему, что может быть плохо. Или вставьте какой-нибудь механизм, где только один экземпляр может обновлять схему.
Создатели Hibernate не рекомендуют делать это в производственной среде в своей книге «Сохранение Java с Hibernate» :
ВНИМАНИЕ: Мы видели, как пользователи Hibernate пытались использовать SchemaUpdate для автоматического обновления схемы производственной базы данных. Это может быстро закончиться катастрофой и не будет разрешено вашим администратором базы данных.
Проверьте LiquiBase XML для ведения журнала изменений. Я никогда не использовал его до этого года, но обнаружил, что его очень легко освоить и сделать управление ревизиями БД / управление миграцией / изменениями очень надежным. Я работаю над проектом Groovy / Grails, и Grails использует Hibernate для всех своих ORM (называемых «GORM»). Мы используем Liquibase для управления всеми изменениями схемы SQL, что мы делаем довольно часто, так как наше приложение развивается с новыми функциями.
По сути, вы храните XML-файл наборов изменений, которые вы продолжаете добавлять по мере развития вашего приложения. Этот файл хранится в git (или как вы используете) с остальной частью вашего проекта. Когда ваше приложение развернуто, Liquibase проверяет его таблицу изменений в БД, к которой вы подключаетесь, чтобы узнать, что уже применено, а затем разумно просто применяет любые изменения, которые еще не были применены из файла. На практике он работает великолепно, и если вы используете его для всех изменений схемы, вы можете быть на 100% уверены, что код, который вы извлекаете и разворачиваете, всегда сможет подключиться к полностью совместимой схеме базы данных.
Удивительная вещь в том, что я могу взять на своем ноутбуке совершенно пустую базу данных mysql, запустить приложение и сразу же настроить схему для меня. Это также облегчает тестирование изменений схемы, применяя их сначала к локальной dev-системе или промежуточной базе данных.
Самый простой способ начать работу с ним, вероятно, состоит в том, чтобы взять существующую БД и затем использовать Liquibase для создания исходного файла baseline.xml. Тогда в будущем вы можете просто добавить к нему и позволить liquibase взять на себя управление изменениями схемы.
hbm2ddl.auto=update
так, чтобы ваши сопоставления классов / БД были проверены и вы имели полный контроль над созданием БД с помощью ликвидазы. Что вы думаете?
validate
Я бы проголосовал нет. Hibernate, кажется, не понимает, когда типы данных для столбцов изменились. Примеры (с использованием MySQL):
String with @Column(length=50) ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)
@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed
Возможно, есть и другие примеры, такие как увеличение длины столбца String более чем на 255 и его преобразование в текст, средний текст и т. Д. И т. Д.
Конечно, я не думаю, что на самом деле есть способ «преобразовать типы данных» без создания нового столбца, копирования данных и удаления старого столбца. Но в ту минуту, когда в вашей базе данных есть столбцы, которые не отражают текущее отображение Hibernate, вы живете очень опасно ...
Flyway - хороший вариант для решения этой проблемы:
@Column(length = 45)
на @Column(length = 255)
. Можно убедиться, что Hibernate 4.3.6.Final правильно обновил схему базы данных, используя hbm2ddl.auto=update
. (Стоит упомянуть, что в базе данных в настоящее время нет никаких данных - только структура.)
Hibernate должен поставить заявление об отказе от использования автоматических обновлений в prod, чтобы скрыть себя, когда люди, которые не знают, что делают, используют его в ситуациях, когда его не следует использовать.
Разумеется, ситуации, когда его не следует использовать, намного превосходят те, где все в порядке.
Я использовал его в течение многих лет во многих различных проектах, и у меня никогда не было ни одной проблемы. Это не плохой ответ, и это не ковбойское кодирование. Это исторический факт.
Человек, который говорит «никогда не делай этого на производстве», думает о конкретном наборе производственных развертываний, а именно о тех, с которыми он знаком (его компания, его отрасль и т. Д.).
Вселенная «производственных развертываний» обширна и разнообразна.
Опытный разработчик Hibernate точно знает, что DDL получит в результате данной конфигурации сопоставления. Пока вы тестируете и проверяете, что то, что вы ожидаете, попадает в DDL (в dev, qa, staging и т. Д.), У вас все в порядке.
Когда вы добавляете много функций, автоматические обновления схемы могут быть в режиме реального времени.
Список автоматических обновлений, которые не будут обрабатываться, бесконечен, но некоторые примеры - миграция данных, добавление необнуляемых столбцов, изменение имени столбца и т. Д. И т. Д.
Также вам нужно позаботиться в кластерной среде.
Но опять же, если бы вы знали все это, вы бы не задавали этот вопрос. Хм , , Хорошо, если вы задаете этот вопрос, вам следует подождать, пока у вас не будет большого опыта работы с Hibernate и автоматическим обновлением схемы, прежде чем подумать об использовании его в prod.
Как я объяснил в этой статье , это не очень хорошая идея для использования hbm2ddl.auto
в производстве.
Единственный способ управлять схемой базы данных - использовать сценарии инкрементной миграции, потому что:
Даже руководство пользователя Hibernate советует вам избегать использования hbm2ddl
инструмента в производственных средах.
SchemaExport
как продемонстрировано в этом тесте .
Мы делаем это в проекте, работающем уже несколько месяцев, и до сих пор у нас не было проблем. Имейте в виду 2 ингредиента, необходимые для этого рецепта:
Проектируйте свою объектную модель с подходом обратной совместимости, то есть осуждайте объекты и атрибуты, а не удаляя / изменяя их. Это означает, что если вам нужно изменить имя объекта или атрибута, оставьте старое как есть, добавьте новое и напишите какой-нибудь скрипт миграции. Если вам нужно изменить связь между объектами, если вы уже находитесь в производстве, это означает, что ваш проект был в первую очередь неправильным, поэтому постарайтесь придумать новый способ выражения новых отношений, не затрагивая старые данные.
Всегда делайте резервную копию базы данных перед развертыванием.
Я чувствую - после прочтения этого поста - что 90% людей, принимающих участие в этом обсуждении, приходят в ужас от мысли об использовании подобных автоматизаций в производственной среде. Некоторые бросают мяч в DBA. Уделите немного времени, чтобы учесть, что не все производственные среды предоставляют DBA, и не так много команд разработчиков могут себе их позволить (по крайней мере, для проектов среднего размера). Так что, если мы говорим о командах, где каждый должен делать все, мяч на них.
В таком случае, почему бы просто не попытаться получить лучшее из обоих миров? Такие инструменты здесь, чтобы помочь, которые - с продуманным дизайном и планом - могут помочь во многих ситуациях. И поверьте мне, поначалу администраторов может быть трудно убедить, но если они знают, что мяч не в их руках, им это понравится.
Лично я никогда не вернусь к написанию сценариев вручную для расширения любого типа схемы, но это только мое мнение. И после того, как я недавно начал принимать NoSQL-схемы без баз данных, я вижу, что более чем скоро все эти операции на основе схем уйдут в прошлое, поэтому вам лучше начать менять свою перспективу и смотреть в будущее.
Я бы не стал рисковать, потому что вы можете потерять данные, которые должны были быть сохранены. hbm2ddl.auto = update - это простой способ поддерживать вашу базу данных в актуальном состоянии.
В моем случае (Hibernate 3.5.2, Postgresql, Ubuntu) настройка hibernate.hbm2ddl.auto=update
только создавала новые таблицы и создавала новые столбцы в уже существующих таблицах.
Он не удалял ни таблицы, ни столбцы, ни столбцы. Это можно назвать безопасным вариантом, но что-то вроде hibernate.hbm2ddl.auto=create_tables add_columns
будет более понятным.
Это не безопасно, не рекомендуется, но возможно.
У меня есть опыт использования приложения с автоматическим обновлением на производстве.
Итак, основные проблемы и риски, обнаруженные в этом решении:
Так что я не буду рекомендовать использовать автообновление в производстве.
Если вы действительно хотите использовать автообновление в производстве, я рекомендую:
И, в отличие от других постов, я не думаю, что автообновление включено, это связано с «очень хорошо оплачиваемыми» администраторами баз данных (как упоминалось в других постах). У администраторов баз данных есть более важные дела, чем писать операторы SQL для создания / изменения / удаления таблиц и столбцов. Эти простые каждодневные задачи могут быть выполнены и автоматизированы разработчиками и переданы только команде DBA для просмотра, не требуя, чтобы Hibernate и администраторы баз данных "очень хорошо оплачивались" для их написания.
Обычно корпоративные приложения в крупных организациях работают с ограниченными привилегиями.
Имя пользователя базы данных может не иметь DDL
привилегии для добавления столбцов, что hbm2ddl.auto=update
требует.
Я согласен с Владимиром. Администраторы в моей компании определенно не оценили бы это, если бы я даже предложил такой курс.
Кроме того, создание сценария SQL вместо слепо доверяющего Hibernate дает возможность удалять поля, которые больше не используются. Hibernate не делает этого.
И я считаю, что сравнение производственной схемы с новой схемой дает вам еще лучшее понимание того, как вы изменились в модели данных. Вы знаете, конечно, потому что вы сделали это, но теперь вы видите все изменения за один раз. Даже те, которые заставляют вас идти, как "Какого черта ?!"
Существуют инструменты, которые могут сделать дельту схемы для вас, так что это даже не тяжелая работа. И тогда вы точно знаете, что произойдет.
Схема приложений может развиваться во времени; если у вас есть несколько установок, которые могут быть в разных версиях, у вас должен быть какой-то способ убедиться, что ваше приложение, какой-либо инструмент или сценарий способны поэтапно переносить схему и данные из одной версии в любую следующую.
Вся ваша настойчивость в отображениях (или аннотациях) Hibernate является очень хорошим способом для контроля над развитием схемы.
Следует учитывать, что эволюция схемы имеет несколько аспектов, которые следует учитывать:
эволюция схемы базы данных с добавлением дополнительных столбцов и таблиц
удаление старых столбцов, таблиц и отношений
заполнение новых столбцов значениями по умолчанию
Инструменты гибернации важны, в частности, в том случае, если (как показывает мой опыт) у вас разные версии одного и того же приложения в разных типах баз данных.
Точка 3 очень чувствительна в том случае, если вы используете Hibernate, как в случае, если вы вводите новое булево значение или числовое свойство, если Hibernate найдет какое-либо нулевое значение в таких столбцах, если вызовет исключение.
Итак, что я хотел бы сделать: действительно использовать возможности инструментов гибрида Hibernate для обновления схемы, но вы должны добавить наряду с этим некоторый обратный вызов для обслуживания данных и схемы, например, для заполнения значений по умолчанию, отбрасывания больше не используемых столбцов и тому подобного. Таким образом, вы получаете преимущества (независимые от базы данных сценарии обновления схемы и избегаете дублирования кодирования обновлений, в постоянстве и в сценариях), но вы также охватывает все аспекты операции.
Так, например, если обновление версии заключается просто в добавлении свойства со значением varchar (следовательно, столбца), которое по умолчанию может иметь значение null, с автоматическим обновлением все будет готово. Там, где требуется больше сложности, потребуется больше работы.
Это предполагает, что приложение при обновлении способно обновлять свою схему (это может быть сделано), что также означает, что оно должно иметь права пользователя для этого в схеме. Если политика клиента предотвращает это (скорее всего, случай с Ящерицей), вам придется предоставить сценарии, специфичные для базы данных.