Hibernate: hbm2ddl.auto=обновление в производстве?
можно ли запускать приложения Hibernate, настроенные с помощью hbm2ddl.auto=update
обновить схему базы данных в производственной среде?
15 ответов
нет, это небезопасно.
несмотря на все усилия команды Hibernate, вы просто не можете полагаться на автоматическое обновление производства. Напишите свои собственные патчи, просмотрите их с помощью DBA, протестируйте их, а затем примените их вручную.
теоретически, если обновление hbm2ddl работало в развитии, оно должно работать в продукции тоже. Но на самом деле это не всегда так.
даже если он работал нормально, он может быть неоптимальным. Администраторы платят, что и не просто так.
мы делаем это в производстве, хотя и с приложением, которое не является критически важным и без высокооплачиваемых DBAs на персонал. Это всего лишь один ручной процесс, который подвержен человеческой ошибке-приложение может обнаружить разницу и сделать все правильно, плюс вы предположительно протестировали его в различных средах разработки и тестирования.
одно предостережение - в кластерной среде вы можете избежать этого, потому что несколько приложений могут появиться одновременно и попытаться изменить схема, которая может быть плохой. Или поместите какой-то механизм, где только одному экземпляру разрешено обновлять схему.
создатели Hibernate не рекомендуют делать это в производственной среде в своей книге "Java Persistence with Hibernate":
предупреждение: мы видели пользователей Hibernate, пытающихся использовать SchemaUpdate для автоматического обновления схемы производственной базы данных. Это может быстро закончиться катастрофой и не будет разрешено вашим DBA.
Проверьте LiquiBase XML для хранения журнала изменений обновлений. Я никогда не использовал его до этого года, но я обнаружил, что его очень легко узнать и сделать управление ревизией/миграцией/изменениями DB очень надежным. Я работаю над проектом Groovy / Grails, а Grails использует Hibernate для всех своих ORM (называемых "GORM"). Мы используем Liquibase для управления всеми изменениями схемы SQL, что мы делаем довольно часто, поскольку наше приложение развивается с новыми функциями.
в основном, вы держите XML-файл наборы изменений, которые вы продолжаете добавлять по мере развития приложения. Этот файл хранится в Git (или что вы используете) с остальной частью вашего проекта. Когда ваше приложение развернуто, Liquibase проверяет, что это таблица изменений в БД, к которой вы подключаетесь, чтобы она знала, что уже было применено, а затем разумно просто применяет все наборы изменений, которые еще не были применены из файла. Он отлично работает на практике, и если вы используете его для всех изменений схемы, вы можете быть 100% уверены, что код, который вы проверяете и развертываете, всегда сможет подключиться к полностью совместимой схеме базы данных.
удивительная вещь заключается в том, что я могу взять абсолютно пустую базу данных mysql на моем ноутбуке, запустить приложение, и сразу же схема настроена для меня. Это также упрощает тестирование изменений схемы, применяя их сначала к локальному разработчику или промежуточной БД.
самый простой способ начать работу с ним, вероятно, будет взять существующую БД, а затем использовать Liquibase для создания начальной базовой линии.XML-файл. Тогда в будущем вы можете просто добавить к ним и пусть при взять на себя управление изменениями схемы.
Я бы проголосовал нет. 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
вероятно, есть и другие примеры, такие как нажатие длины столбца строки выше 255 и его преобразование в текст, mediumtext и т. д.
конечно, я не думаю, что есть способ "конвертировать типы данных" без создания нового столбца, копирования данных и сдувания старого столбца. Но минута в вашей базе данных есть столбцы, которые не отражают текущее отображение спящего режима, в котором вы живете очень опасно...
Flyway-хороший вариант для решения этой проблемы:
Hibernate должен поставить отказ от ответственности за не использование автоматических обновлений в prod, чтобы покрыть себя, когда люди, которые не знают, что они делают, используют его в ситуациях, когда он не должен использоваться.
предоставил ситуации, в которых он не должен использоваться, значительно превосходят те, где это нормально.
Я использовал его в течение многих лет на многих проектах, и никогда не имел ни единого вопроса. Это не дурацкий ответ, и это не ковбойское кодирование. Это исторический факт.
человек, который говорит: "никогда не делайте этого в производстве", думает о конкретном наборе производственных развертываний, а именно о тех, с которыми он знаком (его компания, его промышленность и т. д.).
Вселенная "производственных развертываний" обширна и разнообразна.
опытный разработчик Hibernate точно знает, что DDL будет результатом данной конфигурации сопоставления. Пока вы тестируете и проверяете, что то, что вы ожидаете, заканчивается в DDL (в dev, qa, постановка и т. д.), Вы в порядке.
когда вы добавляете много функций, автоматическое обновление схемы может быть в режиме реального времени.
список автоматических обновлений не будет обрабатывать бесконечен, но некоторые примеры-миграция данных, добавление ненулевых столбцов, изменения имен столбцов и т. д.
Также вам нужно позаботиться в кластеризованных средах.
но опять же, если бы вы знали все это, вы бы не задавали этот вопрос. Хм. . . Хорошо, если вы задав этот вопрос, вы должны подождать, пока у вас будет много опыта работы с обновлениями Hibernate и auto schema, прежде чем думать об использовании его в prod.
Как я объяснил в в этой статье, это не очень хорошая идея использовать hbm2ddl.auto
в производстве.
единственный способ управления схемой базы данных-использовать сценарии инкрементной миграции, потому что:
- скрипты будут находиться в VCS вдоль вашей базы кода. Когда вы проверяете ветку, вы воссоздаете всю схему с нуля.
- инкрементные скрипты могут быть протестированы на сервере QA перед применением в производстве
- там нет необходимости в ручном вмешательстве, так как скрипты могут выполняться Flyway, следовательно, это уменьшает вероятность человеческой ошибки, связанной с запуском сценариев вручную.
даже Hibernate Руководство Пользователя советую вам избегать использования hbm2ddl
инструмент для производственных сред.
мы делаем это в проекте, работающем в производстве в течение нескольких месяцев, и до сих пор у нас не было проблем. Имейте в виду 2 Ингредиенты, необходимые для этого рецепта:
создайте свою объектную модель с подходом обратной совместимости, то есть deprecate объекты и атрибуты, а не их удаление/изменение. Это означает, что если вам нужно изменить имя объекта или атрибута, оставить старый как есть, добавить и написать какой-то миграции скрипт. Если вам нужно изменить связь между объектами, если вы уже находитесь в производстве, это означает, что ваш дизайн был неправильным в первую очередь, поэтому попробуйте придумать новый способ выражения новых отношений, не затрагивая старые данные.
всегда резервное копирование база данных до развертывания.
мое чувство - после прочтения этого сообщения-что 90% людей, принимающих участие в этой дискуссии, ужасаются только с мысль об использовании автоматизации в производственной среде. Некоторые бросок мяча в DBA. Однако подумайте, что не все производственные среды будут предоставлять DBA, и не многие команды разработчиков могут позволить себе один (по крайней мере, для проектов среднего размера). Итак, если мы говорим о командах, где каждый должен делать все, мяч на них.
в этом случае, почему бы просто не попытаться иметь лучшее из обоих миров? Инструменты, как это здесь Дайте руку помощи, которая - при тщательном проектировании и плане-может помочь во многих ситуациях. И поверьте мне, администраторов поначалу может быть трудно убедить, но если они знают, что мяч не на их руках, им это понравится.
лично я бы никогда не вернулся к написанию сценариев вручную для расширения любого типа схемы, но это только мое мнение. И после того, как недавно я начал принимать базы данных без схемы NoSQL, я вижу, что более чем скоро все эти схемы операции будут принадлежать прошлому, поэтому вам лучше начать менять свою перспективу и смотреть вперед.
Я бы не стал рисковать, потому что вы можете потерять данные, которые должны были быть сохранены. hbm2ddl.auto=update-это простой способ поддерживать базу данных dev в актуальном состоянии.
в моем случае (Hibernate 3.5.2, Postgresql, Ubuntu), настройка
hibernate.hbm2ddl.auto=update
только создавал новые таблицы и создавал новые столбцы в уже существующих таблицах.это не удалять таблицы, ни столбцы, ни изменить столбцы. Его можно назвать безопасным вариантом, но что-то вроде
hibernate.hbm2ddl.auto=create_tables add_columns
было бы более понятно.
Нет, никогда не делай это. Hibernate не обрабатывает миграцию данных. Да, это сделает вашу схему выглядеть правильно, но это не гарантирует, что ценные производственные данные не теряются в процессе.
Это небезопасно, не рекомендуется, но это возможно.
У меня есть опыт работы в приложении с использованием опции автоматического обновления в производстве.
ну, основные проблемы и риски, обнаруженные в этом решении:
- Deploy в неправильной базе данных. Если вы совершаете ошибку, чтобы запустить сервер приложений со старой версией приложения (EAR/WAR/etc) в неправильной базе данных... У вас будет много новых столбцов, таблиц, иностранных ключи и ошибки. Та же проблема может возникнуть с простой ошибкой в файле источника данных (скопируйте/вставьте файл и забыли изменить базу данных). В резюме, ситуация может быть катастрофой в вашей базе данных.
- сервер приложений слишком долго запускается. Это происходит потому, что Hibernate пытается найти все созданные таблицы/столбцы/и т. д. Каждый раз при запуске приложения. Он делает это, чтобы знать, что (таблица, столбец и т. д.) Нужно создать. Эта проблема будет только получает хуже.
- инструменты базы данных это почти невозможно использовать. Чтобы создать скрипты для базы данных, нужно подумать о том, что будет создано автообновлением после запуска сервера приложений. Если вам нужно заполнить новый столбец (например) некоторыми данными, вам нужно запустить сервер приложений, дождаться спящего режима Крита нового столбца и запустить сценарий SQL после этого. Такие инструменты, как Flyway, почти невозможно использовать с автоматическим обновлением включен.
- изменения базы данных не централизованы. С возможностью Hibernate создавать таблицы и все остальное, трудно следить за изменениями в базе данных в каждой версии приложения, потому что большинство из них происходит автоматически.
- поощряет мусор на базе данных. Из-за простоты автоматического обновления есть шанс, что ваша команда пренебрегает удалением старых столбцов и старых таблиц.
- неминуема катастрофы. Неизбежный риск возникновения какой-либо катастрофы на производстве (как некоторые люди, упомянутые в других ответах). Даже с приложением, работающим и обновляемым в течение многих лет, я не думаю, что это безопасно. Я никогда не чувствовал себя в безопасности.
Итак, я не буду рекомендовать использовать автоматическое обновление в производстве.
Если вы действительно хотите использовать автоматическое обновление производства, я рекомендую:
- разделенных сетей. Тестовая среда не может получить доступ к homolog окружающей среды. Это помогает предотвратить развертывание, которое должно было быть в тестовой среде, изменить базу данных Омологаций.
- управление скриптами заказа. Вам нужно организовать сценарии для запуска перед развертыванием (изменение таблицы структуры, удаление таблицы/столбцов) и сценарий после развертывания (заполнение информации для новых столбцов/таблиц).
и, в отличие от других сообщений, я не думаю, что автоматическое обновление включено, это связано с " очень хорошо оплачиваемые " DBAs (как упоминалось в других сообщениях)... У DBAs есть более важные вещи, чем писать инструкции SQL для создания/изменения / удаления таблиц и столбцов. Эти простые повседневные задачи могут быть выполнены и автоматизированы разработчиками и переданы только команде DBA для просмотра, не нуждаясь в Hibernate и DBAs "очень хорошо оплачивается", чтобы написать их.
обычно корпоративные приложения в крупных организациях работают с уменьшенными привилегиями.
имя пользователя базы данных может не иметь
DDL
привилегии для добавления столбцов, которыеhbm2ddl.auto=update
требует.
Я согласен с Владимиром. Администраторы в моей компании определенно не оценят, если я даже предложу такой курс.
кроме того, создание SQL-скрипта вместо слепо доверяющего Hibernate дает вам возможность удалять поля, которые больше не используются. Hibernate этого не делает.
и я считаю, что сравнение производственной схемы с новой схемой дает вам еще лучшее представление о том, что вы изменили в модели данных. Ты знаешь, конечно., потому что вы сделали это, но теперь вы видите все изменения за один раз. Даже те, которые заставляют тебя говорить: "какого черта?!".
есть инструменты, которые могут сделать дельту схемы для вас, поэтому это даже не тяжелая работа. И тогда ты точно знаешь, что произойдет.
схема приложений может развиваться во времени; если у вас есть несколько установок, которые могут быть в разных версиях, вы должны иметь какой-то способ гарантировать, что ваше приложение, какой-то инструмент или скрипт способен переносить схему и данные из одной версии пошагово в любую следующую.
наличие всей вашей настойчивости в сопоставлениях Hibernate (или аннотациях) - очень хороший способ держать эволюцию схемы под контролем.
вы должны рассмотреть эту схему эволюция имеет несколько аспектов, которые следует учитывать:
эволюция схемы базы данных в добавление дополнительных столбцов и таблиц
падение старых столбцов, таблиц и отношения
заполнение новых столбцов по умолчанию
Hibernate tools важны, в частности, в случае (как и в моем опыте) у вас есть разные версии одного и того же приложения на многих различных типах баз данных.
Точка 3 очень чувствительна, если вы используете Hibernate, как в случае, если вы вводите новое логическое свойство или числовое, если Hibernate найдет любое нулевое значение в таких столбцах, если вызовет исключение.
Итак, что я бы сделал: действительно используйте емкость инструментов Hibernate для обновления схемы, но вы должны добавить вместе с ней некоторые данные и обратный вызов обслуживания схемы, например, для заполнения значений по умолчанию, удаления больше не используемых столбцов и т. д. Таким образом, вы получите преимущества (независимые от базы данных сценарии обновления схемы и избежать дублирования кодирования обновлений, в peristence и в сценариях), но вы также охватываете все аспекты операции.
например, если обновление версии состоит просто в добавлении свойства varchar (следовательно, столбца), которое может по умолчанию иметь значение null, с автоматическим обновлением вы будете сделаны. Там, где требуется больше сложности, потребуется больше работы.
Это предполагает, что приложение, когда updated способен обновлять свою схему (это можно сделать), что также означает, что он должен иметь права пользователя для этого на схеме. Если политика клиента предотвращает это (вероятно, случай мозга ящерицы), вам придется предоставить скрипты для конкретной базы данных.