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

Spring JPA/Hibernate:在第一次运行时创建数据库模式并导入数据,在后续运行时更新模式,spring,hibernate,jakarta-ee,jpa,persistence.xml,Spring,Hibernate,Jakarta Ee,Jpa,Persistence.xml,在我的项目中,我经常使用JPA/Hibernate堆栈作为数据库 定义persistence.xml时,您有两个选项可以设置hibernate.hbm2ddl.auto。 如果设置为create,则在每次应用程序运行时都将重新创建表(当然,持久化的数据将丢失)。还可以通过使用hibernate.hbm2ddl.import_files设置db fixture来导入初始数据。当设置为update时,将仅创建新实体的表(保留现有表中的持久数据) 问题是,这在开发时不是那么方便,我喜欢这样的行为:

在我的项目中,我经常使用JPA/Hibernate堆栈作为数据库

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

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

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

关于我的典型堆栈的更多信息:SpringWeb应用程序,运行在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>

org.hibernate.ejb.HibernatePersistence

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

只需使用
更新
——如果数据库为空,则
更新
创建
的结果是相同的。

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

请记住,使用
hbm2ddl.auto
只能更新数据库的结构,而不能更新其值

例如:假设你有

@Version
private Long version;
过了一会儿,你发现你宁愿

@Version
@Temporal(TemporalType.TIMESTAMP)
private Date lastModified;
Hibernate对语义的变化没有多少线索,当然也不知道如何相应地转换字段或设置默认值

属性
hbm2ddl.auto
hbm2ddl.import_文件
适用于短期(内存中)数据库(因此也适用于自动集成或验收测试),但不适用于生产环境

我强烈地建议 或我个人使用后者。Nathan在这个工具上做得很好,尽管它的文档缺乏一些细节

也就是说:

-Dhibernate.hbm2ddl.auto=create -Dhibernate.hbm2ddl.import_files=foo.sql

在你的应用程序第一次启动时,你应该做到这一点。只需在
persistence.xml中将
hbm2ddl.auto
的值设置为
update
,谢谢。抱歉造成混淆,但仅使用
update
是不够的。我确实想在创建数据库时导入一些初始数据。我通常使用
hibernate.hbm2ddl.import_files
属性指定初始db fixture,但这种方法仅适用于
hibernate.hbm2ddl.auto
设置为
create
create drop
。我将更新我的帖子以反映这一点。