JPA / Hibernate:首次运行时创建数据库模式并导入数据,后续运行时更新模式

时间:2013-10-24 06:59:42

标签: spring hibernate java-ee jpa persistence.xml

在我的项目中,我经常将JPA / Hibernate堆栈用于数据库。

定义persistence.xml时,您可以选择hibernate.hbm2ddl.auto。 如果设置为create将在每次运行应用程序时重新创建表(当然,持久数据将丢失)。也可以通过使用hibernate.hbm2ddl.import_files设置db fixture来导入初始数据。设置为update时,仅创建新实体的表(将保留现有表中的持久数据)。

问题在于开发时这不方便,我喜欢这样的行为:

  • 在第一次应用程序运行时(当数据库中没有表时) - 像hibernate.hbm2ddl.auto这样的行为被设置为create(基于实体创建表)并导入预定义的数据库夹具
  • 在所有后续运行中 - 像hibernate.hbm2ddl.auto这样的行为设置为update(为新实体创建新表,为旧实体保留表/数据)。

这可以实现这样的事情吗?

关于我的典型堆栈的更多信息:Spring Web应用程序,在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 个答案:

答案 0 :(得分:3)

请注意,使用hbm2ddl.auto您只能更新数据库的结构,而不是它的值。

例如:让我们说你有

@Version
private Long version;

过了一会儿,你发现你宁愿拥有

@Version
@Temporal(TemporalType.TIMESTAMP)
private Date lastModified;

Hibernate没有太多关于语义含义变化的线索,并且肯定不知道如何相应地转换字段或默认设置。

属性hbm2ddl.autohbm2ddl.import_files对于短期(内存中)数据库(以及自动集成或验收测试)很方便,但不适合生产环境。

我会强烈提出类似的建议 scriptellaliquibase。我个人使用后者。 Nathan在这个工具上做得很好,虽然它的文档缺乏一些细节。

话虽如此:

-Dhibernate.hbm2ddl.auto=create -Dhibernate.hbm2ddl.import_files=foo.sql
在您的应用程序的第一次启动

应该做的伎俩。只需在hbm2ddl.auto中将update的值设置为persistence.xml

答案 1 :(得分:1)

只需使用update - 如果数据库为空,则updatecreate的结果相同。

答案 2 :(得分:1)

我有同样的问题,我没有找到任何Hibernate / JPA解决方案。没有任何Hibernate解决方案可供您选择吗?我建议使用liquibase。您可以定义一些初始sqls然后liquibase将在启动时执行它们。它有一个maven插件,所以你可以在你的pom中配置它,然后与maven一起使用。