JPA / Hibernate:在第一次运行时创建数据库模式并导入数据,在后续运行时更新模式 [英] JPA/Hibernate: create database schema and import data on first run, update schema on subsequent runs

查看:109
本文介绍了JPA / Hibernate:在第一次运行时创建数据库模式并导入数据,在后续运行时更新模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,我经常使用JPA / Hibernate堆栈来存储数据库。


$ b 定义 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.0encoding =UTF-8standalone =no?> 
< persistence xmlns =http://java.sun.com/xml/ns/persistencexmlns:xsi =http://www.w3.org/2001/XMLSchema-instanceversion = 2.0xsi:schemaLocation =http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd\">
< persistence-unit name =persistenceUnittransaction-type =RESOURCE_LOCAL>
< provider> org.hibernate.ejb.HibernatePersistence< / provider>
<属性>
< property name =hibernate.dialectvalue =org.hibernate.dialect.MySQL5InnoDBDialect/>
<! - value =create在每次运行中构建新的数据库; value =update来修改现有的数据库; value =create-drop与create相同,但在Hibernate关闭时也会丢弃表; value =validate不会更改数据库 - >
< property name =hibernate.hbm2ddl.autovalue =update/>
< property name =hibernate.ejb.naming_strategyvalue =org.hibernate.cfg.ImprovedNamingStrategy/>
< property name =hibernate.connection.charSetvalue =UTF-8/>
< property name =hibernate.hbm2ddl.import_filesvalue =/ META-INF / spring / import.sql/>
< / properties>
< / persistence-unit>
< /余辉>

请评论你是否需要关于我的应用程序配置/结构的其他信息。

解决方案

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



例如:假设您有

  @Version 
私人长版;

过了一段时间后,您发现您宁可有

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

Hibernate对语义的变化没有多少线索,肯定不知道

属性 hbm2ddl.auto hbm2ddl.import_files 对于短期(内存中)数据库(因此用于自动化集成或验收测试)非常方便,但不适用于生产环境。



我会强烈建议类似于
scriptella liquibase 。我个人使用后者。



这就是说:

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

在您的应用首次启动时应该有所斩获。只需在 persistence.xml 中将 hbm2ddl.auto 的值设置为 update c $ c>。


In my projects I often use JPA/Hibernate stack for database.

When defining persistence.xml you have couple options you can set hibernate.hbm2ddl.auto. If set to create tables will be recreated on every application run (persisted data will be lost of course). It is also possible to import initial data by setting db fixture with hibernate.hbm2ddl.import_files. When set to update only tables for new entities will be created (persisted data in existing tables will be preserved).

The thing is that this is not that convenient while developing and I'd like behavior like this:

  • on first application run (when there is no tables in the database) - act like hibernate.hbm2ddl.auto is set to create (create tables based on entities) and import predefined database fixture
  • on all subsequent runs - act like hibernate.hbm2ddl.auto is set to update (create new tables for new entities, leave tables/data for old entities).

Is this possible to implement something like this?

More Info on my typical stack: Spring web application, running on Tomacat, database is MySql, JPA/Hibernate for database access.

My typical 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>

Please, comment if you need other info about my application configuration/structure.

解决方案

Please keep in mind that using hbm2ddl.auto you can only update the structure of the database, not it's values.

For example: let's say you have

@Version
private Long version;

After a while you find out that you would rather have

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

Hibernate does not have much of a clue about the change in the semantic meaning and for sure would not know how to convert the field accordingly or which default to set.

The properties hbm2ddl.auto and hbm2ddl.import_files are convenient for short lived (in-memory) databases (and thus for automated integration or acceptance tests), but are simply not suitable for production environments.

I would strongly suggest something like scriptella or liquibase. I personally use the latter. Nathan does a great job on the tool, though it's documentation lacks a bit of detail.

That being said:

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

on the first start of your app should do the trick. Just set the value of hbm2ddl.auto to update in your persistence.xml.

这篇关于JPA / Hibernate:在第一次运行时创建数据库模式并导入数据,在后续运行时更新模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆