Как обновить схему базы данных без потери данных с помощью Hibernate?
Представьте, что вы разрабатываете приложение Java EE с использованием Hibernate и JBoss. У вас есть работающий сервер, на котором есть важные данные. Вы выпускаете следующую версию приложения раз в то время (1-2 недели), и у них есть куча изменений в уровне персистентности:
- Новые объекты
- Удаленные объекты
- Изменения типа атрибута
- Изменение имени атрибута
- Изменения отношений
Как вы эффективно настраиваете систему, которая обновляет схему базы данных и сохраняет данные? Насколько я знаю (я могу ошибаться), Hibernate не выполняет alter column, drop/alter constraint.
Спасибо,
Артем Б.
Ответы
Ответ 1
LiquiBase - ваш лучший выбор. У этого есть режим hibernate integration, который использует Hibernate hbm2ddl для сравнения вашей базы данных и вашего отображения гибернации, но вместо автоматического обновления базы данных он выдает файл changelog, который можно проверить до фактического запуска.
В то время как более удобно, любой инструмент, который выполняет сравнение вашей базы данных и сопоставлений спящего режима, будет делать ошибки. См. http://www.liquibase.org/2007/06/the-problem-with-database-diffs.html для примера. С помощью Liquibase вы создаете список изменений базы данных по мере развития в формате, который может выдержать код с помощью ветвей и слияний.
Ответ 2
Я лично отслеживаю все изменения в миграции SQL script.
Ответ 3
http://liquibase.org/
Ответ 4
Вы можете использовать https://github.com/Devskiller/jpa2ddl инструмент, который обеспечивает плагин Maven и Gradle и способен генерировать автоматические миграции схем для Flyway на основе объектов JPA. Он также включает все свойства, диалекты, пользовательские типы, стратегии именования и т.д.
Ответ 5
Для одного приложения я использую SchemaUpdate, который встроен в Hibernate, прямо из класса bootstrap, поэтому схема проверяется каждый раз, когда приложение запускается. Это позаботится о добавлении новых столбцов или таблиц, что в основном происходит с зрелым приложением. Для обработки особых случаев, например, для удаления столбцов, bootstrap просто вручную запускает ddl в try/catch, поэтому, если он уже был сброшен один раз, он просто вызывает ошибку. Я не уверен, что сделаю это с помощью критически важных данных в производственном приложении, но через несколько лет и сотни развертываний у меня никогда не было проблем с ним.
Ответ 6
В качестве дополнительной реакции того, что Натан Воксланд сказал о LiquiBase, приведен пример выполнения миграции под Windows для базы данных mySql:
Поместите соединитель mysql в папку lib в дистрибутиве Liquibase, например.
Создайте свойства файла Liquibase.properties в корневом каталоге дистрибуции ликбазы и вставьте эти повторяющиеся строки:
driver: com.mysql.jdbc.Driver
classpath: lib\\mysql-connector-java-5.1.30.jar
url: jdbc:mysql://localhost:3306/OLDdatabase
username: root
password: pwd
Сгенерировать или получить обновленную базу данных под другим именем, например NEWdatabase.
Теперь вы выделите различия в файле Migration.xml с помощью следующей командной строки:
liquibase diffChangeLog --referenceUrl="jdbc:mysql://localhost:3306/NEWdatabase"
--referenceUsername=root --referencePassword=pwd > C:\Users\ME\Desktop\Migration.xml
Наконец, выполните обновление, используя только что сгенерированный файл Migration.xml:
java -jar liquibase.jar --changeLogFile="C:\Users\ME\Desktop\Migration.xml" update
Примечание. Все эти командные строки должны быть выполнены из домашнего каталога Liquibase, где присутствуют Liquibase.bat/.sh и liquidibase.jar.
Ответ 7
Я использую задачу hbm2ddl ant для генерации моего ddl. Существует опция, которая будет выполнять изменения таблиц/столбцов в вашей базе данных.
Обратитесь к атрибуту "update" задачи hbm2ddl ant:
http://www.hibernate.org/hib_docs/tools/reference/en/html/ant.html#d0e1137
update (по умолчанию: false): попытайтесь создать обновление script, представляющее "дельта" между тем, что находится в базы данных и какие отображения указывать. Игнорировать создание/обновление атрибутов. (Не используйте против производственных баз данных, никаких гарантий в все, что может быть надлежащей дельтой или что основной база данных может фактически выполнить необходимые операции)
Ответ 8
Вы также можете использовать DBMigrate. Он похож на Liquibase:
Подобно 'rake migrate' для Ruby on Rails эта библиотека позволяет вам управлять обновление базы данных для вашей Java приложения.