JPA/Hibernate: создание схемы базы данных и импорт данных при первом запуске, обновление схемы при последующих запусках
В своих проектах я часто использую стек JPA/Hibernate для базы данных.
При определении persistence.xml
у вас есть пара вариантов, которые вы можете установить hibernate.hbm2ddl.auto
, Если установлено create
таблицы будут воссозданы при каждом запуске приложения (сохраненные данные будут потеряны, конечно). Также можно импортировать исходные данные, установив в db fixture hibernate.hbm2ddl.import_files
, Когда установлено update
Будут созданы только таблицы для новых объектов (сохраненные данные в существующих таблицах будут сохранены).
Дело в том, что это не очень удобно при разработке, и мне бы хотелось, чтобы поведение было таким:
- при первом запуске приложения (когда в базе данных нет таблиц) - действуйте как
hibernate.hbm2ddl.auto
установлен вcreate
(создавать таблицы на основе сущностей) и импортировать предопределенную фикстуру базы данных - на всех последующих трассах - действуй как
hibernate.hbm2ddl.auto
установлен вupdate
(создать новые таблицы для новых сущностей, оставить таблицы / данные для старых сущностей).
Возможно ли реализовать что-то подобное?
Дополнительная информация о моем типичном стеке: веб-приложение Spring, работающее на Tomacat, база данных MySql, JPA/Hibernate для доступа к базе данных.
Мой типичный persistence.xml
:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database -->
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
<property name="hibernate.connection.charSet" value="UTF-8"/>
<property name="hibernate.hbm2ddl.import_files" value="/META-INF/spring/import.sql"/>
</properties>
</persistence-unit>
</persistence>
Пожалуйста, прокомментируйте, если вам нужна другая информация о конфигурации / структуре моего приложения.
3 ответа
Пожалуйста, имейте в виду, что с помощью hbm2ddl.auto
Вы можете только обновить структуру базы данных, а не ее значения.
Например: скажем, у вас есть
@Version
private Long version;
Через некоторое время вы узнаете, что вы бы предпочли
@Version
@Temporal(TemporalType.TIMESTAMP)
private Date lastModified;
Hibernate не имеет ни малейшего представления об изменении семантического значения и наверняка не знает, как преобразовать поле соответствующим образом или какое значение по умолчанию установить.
Свойства hbm2ddl.auto
а также hbm2ddl.import_files
удобны для кратковременных (в памяти) баз данных (и, следовательно, для автоматической интеграции или приемочных тестов), но просто не подходят для производственных сред.
Я бы настоятельно рекомендовал что-то вроде Scriptella или liquibase Я лично использую последнее. Натан отлично справляется с этим инструментом, хотя в его документации не хватает деталей.
Что, как говорится:
-Dhibernate.hbm2ddl.auto=create -Dhibernate.hbm2ddl.import_files=foo.sql
при первом запуске вашего приложения нужно сделать свое дело. Просто установите значение hbm2ddl.auto
в update
в вашем persistence.xml
,
Просто используйте update
- если база данных пуста, то результат для update
а также create
та же.
У меня была такая же проблема, и я не нашел никаких решений Hibernate/JPA. Есть ли какое-либо решение Hibernate вариант для вас? Я могу предложить использовать ликвазы. Вы можете определить некоторые начальные sqls, а затем liquibase выполнит их при запуске. Он имеет плагин maven, так что вы можете настроить его в pom, а затем использовать его с maven.