Hibernate hbm2ddl.auto配置的可能值是什么,它们做什么?


1084

我真的想更多地了解更新,导出以及可以提供的值,hibernate.hbm2ddl.auto
我需要知道何时使用更新,何时不使用更新?还有什么选择?

这些是可能在数据库上发生的更改:

  • 新表
  • 旧表中的新列
  • 列已删除
  • 列的数据类型已更改
  • 列的类型更改了其属性
  • 桌子掉了
  • 列的值已更改

在每种情况下,最佳解决方案是什么?

Answers:


1082

社区文档

hibernate.hbm2ddl.auto创建SessionFactory时,自动将模式DDL验证或导出到数据库。使用create-drop时,显式关闭SessionFactory时将删除数据库架构。

例如验证| 更新| 创建| 创建放置

因此,可能的选项列表是

  • validate:验证模式,不对数据库进行任何更改。
  • update:更新架构。
  • create:创建模式,销毁先前的数据。
  • create-drop:在显式关闭SessionFactory时(​​通常在应用程序停止时),删除架构。
  • none:对模式不执行任何操作,不对数据库进行任何更改

这些选项似乎旨在作为开发人员的工具,而不是为了促进任何生产级别的数据库,您可能需要查看以下问题;休眠:hbm2ddl.auto =正在生产中更新?


14
只需阅读休眠文档...以获得有效值,它说:“ eg” ...还有其他有效值吗?
塔萨斯

16
我认为它说“ eg”是因为它只是社区文档,如果有人对所有可能的值都感兴趣,则可以在Hibernate的javadoc中找到它。(是的,只有四个选项都存在) docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/cfg/...
szegedi

4
validate说验证模式,这到底是什么意思?
侯赛因·阿赫塔尔·瓦希德

6
如果您希望休眠不执行任何操作,也可以使用“ aardvark”或“ pigeon”或其他任何单词。当然,我不建议这样做!
Ward

2
对create-drop选项的一小部分补充。如果使用此选项,则不会删除整个架构,而是会删除运行此映射时可用的表。例如,如果与图式S上的数据库有A,B,C的表和Java代码具有映射A和B仅然后Hibernate不会删除该表C.
阿迪蒂亚

194

还有一个未记录的值“ none”可以完全禁用它。


7
这实际上非常有用,因为Hibernate的架构验证有时对于完全有效的架构失败。
Michael Piefel 2012年

我正要问这样的事情。我的目的是减少启动时间。
digao_mb 2013年

46
“空字符串”比“无”更好。无: - :使用“无”,您将收到警告信息org.hibernate.cfg.SettingsFactory无法识别的值“hibernate.hbm2ddl.auto”
OKWAP

14
我已经修补了。添加“无”作为显式有效的常量。
桑讷(Sanne),

9
我喜欢“ hibernate.hbm2ddl.auto = potato”而不是其他stackoverflow.com/a/15810379/838444
Sneg 2016年

161

配置属性称为 hibernate.hbm2ddl.auto

在我们的开发环境中,我们设置hibernate.hbm2ddl.auto=create-drop为每次部署时都删除并创建一个干净的数据库,以使数据库处于已知状态。

从理论上讲,您可以设置hibernate.hbm2ddl.auto=update使用模型更改来更新数据库,但是我不相信在生产数据库上这样做。该文档的早期版本说,这至少是试验性的;我不知道目前的状态。

因此,对于我们的生产数据库,请勿设置hibernate.hbm2ddl.auto-默认为不更改数据库。相反,我们手动创建一个SQL DDL更新脚本,该脚本将更改从一个版本应用到下一个版本。


5
实际上,根据文档,create-drop创建数据库表并在会话工厂显式关闭时删除它们。它并没有在创建会话工厂时删除表。
弗朗斯2014年

4
不,创建sessionfactory时,create-drop和create都会删除表,然后在sessionfactory关闭时,create-drop也将删除表。参见stackoverflow.com/a/6752698/1536382
Testo Testini 2015年

在生产中进行hibernate.hbm2ddl.auto = create-drop会导致生产中的多个连接超时吗?
METTAIBI'2


51

尽管这是一篇很老的文章,但是由于我对此主题进行了一些研究,所以想分享它。

hibernate.hbm2ddl.auto

根据文档,它可以具有四个有效值:

创建| 更新| 验证| 创建放置

以下是这些值显示的行为的说明:

  • create:-创建模式,该模式中先前存在的数据(如果存在)将丢失
  • 更新:-使用给定的值更新架构。
  • 验证:-验证架构。它不会更改数据库。
  • create-drop:-通过销毁先前存在的数据(如果存在)来创建模式。当SessionFactory关闭时,它也会删除数据库架构。

以下是值得注意的要点:

  • update的情况下,如果数据库中不存在架构,则会创建该架构。
  • 对于validate,如果模式在数据库中不存在,则不会创建它。相反,它将引发错误:-Table not found:<table name>
  • create-drop的情况下,关闭会话时不会删除架构。它仅在关闭SessionFactory时下降。
  • 如果我给此属性提供任何值(例如abc,而不是上面讨论的上述四个值),或者它留为空白。它显示以下行为:

    -如果数据库中不存在模式:-它创建模式

    -如果数据库中存在模式:- 更新模式。


当使用“更新”时,如果不存在架构,将创建架构确实是非常重要的一点。
yuranos

比较“行为解释”和“重要点”语句时,create-drop是矛盾的。
VNT

2
updateempty有什么区别?
yashjain12yj

46

首先,hbm2ddl配置属性的可能值为以下值:

  • none-不执行任何操作。该架构将不会生成。
  • create-only -将生成数据库模式。
  • drop -之后将删除并创建数据库模式。
  • create -之后将删除并创建数据库模式。
  • create-drop-之后将删除并创建数据库模式。关闭时SessionFactory,数据库架构将被删除。
  • validate -将使用实体映射来验证数据库模式。
  • update -通过将现有数据库架构与实体映射进行比较来更新数据库架构。

我在博客文章中介绍了最常见的Hibernate DDL生成策略

  1. hibernate.hbm2ddl.auto="update"如果您打算添加功能或执行一些自定义脚本,则方便但不灵活。
  2. 最灵活的方法是使用迁飞

但是,即使使用Flyway,仍然可以使用hbm2ddl生成初始迁移脚本。在本文中,您将看到如何将JPA实体模型与jOOQ表模型结合起来。


27

hibernate.hbm2ddl.auto 创建sessionFactory时,将自动验证DDL并将其导出到架构。

默认情况下,它不会在数据库上自动执行任何创建或修改。如果用户设置以下值之一,则表示正在执行DDL模式更改。

  • 创建-正在创建模式

    <entry key="hibernate.hbm2ddl.auto" value="create">
  • 更新-更新现有架构

    <entry key="hibernate.hbm2ddl.auto" value="update">
  • 验证-验证现有架构

    <entry key="hibernate.hbm2ddl.auto" value="validate">
  • create-drop-在会话开始和结束时自动创建和删除模式

    <entry key="hibernate.hbm2ddl.auto" value="create-drop">

2
<entry key =“ hibernate.hbm2ddl.auto” value =“ none”>呢?
VNT

17

如果您不想在应用程序中使用字符串,并且正在寻找预定义的常量,请查看org.hibernate.cfg.AvailableSettingsHibernate JAR中包含的类,您将在其中找到所有可能设置的常量。以您的情况为例:

/**
 * Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
 * <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
 */
String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";

5
为什么要在直接答案上方引用700多行长的源文件,并且产生近500场田鼠跳跳?
帕维尔·尼多巴

...这个问题没有任何意义。为什么有东西?我为什么还要在这里?
specializt

8
  • validate:验证架构,数据库没有任何变化。
  • update:使用当前的执行查询更新架构。
  • create:每次创建新的架构,并销毁先前的数据。
  • create-drop:在停止应用程序或显式关闭SessionFactory时删除架构。

什么是“官方”文档参考?-只是想知道...
Dirk Schumacher


4

validate:它将验证模式,并且不对数据库进行任何更改。
假设您已在映射文件中添加了新列并执行插入操作,由于现有架构与您要插入的对象不同,它将引发异常“缺少XYZ列”。如果您通过手动添加新列来更改表,然后执行插入操作,则它将肯定会将所有列以及新列插入到表中。意味着它不会对现有的架构/表进行任何更改/更改。

update:执行操作时,它将更改数据库中的现有表。您可以使用hbm2ddl选项添加或删除列。但是,如果要添加“ NOT NULL”的新列,则它将忽略将特定列添加到数据库。因为如果要向现有表添加“ NOT NULL”列,则表必须为空。


3

从5.0开始,您现在可以在专用的Enum:中查找这些值:(从5.2开始org.hibernate.boot.SchemaAutoTooling增加了值NONE)。

甚至更好的是,从5.1开始,您还可以使用结合了JPA 2和“旧式” Hibernate DDL操作的。org.hibernate.tool.schema.Action Enum

但是,您尚不能DataSource以此方式进行程序配置。最好将其与结合使用,org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO但当前代码需要一个String值(摘自SessionFactoryBuilderImpl):

this.schemaAutoTooling = SchemaAutoTooling.interpret( (String) configurationSettings.get( AvailableSettings.HBM2DDL_AUTO ) );

……以及enum两者的内部价值,org.hibernate.boot.SchemaAutoToolingorg.hibernate.tool.schema.Action没有公开披露。

以下是一个示例编程DataSource配置(在我的Spring Boot应用程序中使用),由于使用了gambit,.name().toLowerCase()但它仅适用于不带破折号的值(create-drop例如,不适用):

@Bean(name = ENTITY_MANAGER_NAME)
public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory(
        EntityManagerFactoryBuilder builder,
        @Qualifier(DATA_SOURCE_NAME) DataSource internalDataSource) {

    Map<String, Object> properties = new HashMap<>();
    properties.put(AvailableSettings.HBM2DDL_AUTO, SchemaAutoTooling.CREATE.name().toLowerCase());
    properties.put(AvailableSettings.DIALECT, H2Dialect.class.getName());

    return builder
            .dataSource(internalDataSource)
            .packages(JpaModelsScanEntry.class, Jsr310JpaConverters.class)
            .persistenceUnit(PERSISTENCE_UNIT_NAME)
            .properties(properties)
            .build();
}

0

向谁搜索默认值...

它使用spring-boot 2.0.5版和JpaProperties 1.1.0版的源代码编写:

    /**
     * DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto"
     * property. Defaults to "create-drop" when using an embedded database and no
     * schema manager was detected. Otherwise, defaults to "none".
     */
    private String ddlAuto;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.