【问题标题】:JPA/Hibernate: create database schema and import data on first run, update schema on subsequent runsJPA/Hibernate:在第一次运行时创建数据库模式并导入数据,在后续运行时更新模式
【发布时间】:2013-10-24 06:59:41
【问题描述】:

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

定义persistence.xml 时,您有几个选项可以设置hibernate.hbm2ddl.auto。 如果设置为create,将在每次应用程序运行时重新创建表(当然,持久化数据会丢失)。也可以通过使用hibernate.hbm2ddl.import_files 设置db 夹具来导入初始数据。当设置为 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>

如果您需要有关我的应用程序配置/结构的其他信息,请发表评论。

【问题讨论】:

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


    【解决方案1】:

    请记住,使用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
    

    在您的应用程序的第一次启动时应该可以解决问题。只需在您的persistence.xml 中将hbm2ddl.auto 的值设置为update

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢。很抱歉造成混淆,但使用 update 是不够的。我确实想导入一些有关数据库创建的初始数据。我通常使用hibernate.hbm2ddl.import_files 属性来指定初始数据库夹具,但这种方法仅适用于将hibernate.hbm2ddl.auto 设置为createcreate-drop。我会更新我的帖子以反映这一点。
      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2011-05-01
        • 2013-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-22
        • 2011-08-19
        • 1970-01-01
        相关资源
        最近更新 更多