【问题标题】:What are the possible values of the Hibernate hbm2ddl.auto configuration and what do they doHibernate hbm2ddl.auto 配置的可能值是什么,它们的作用是什么
【发布时间】:2010-10-01 02:09:12
【问题描述】:

我真的很想知道更多关于更新、导出和可以给hibernate.hbm2ddl.auto的值
我需要知道何时使用更新,何时不使用?还有什么替代方案?

这些是可能发生在 DB 上的更改:

  • 新表格
  • 旧表中的新列
  • 列已删除
  • 列的数据类型已更改
  • 一种类型的列改变了它的属性
  • 表已删除
  • 一列的值改变了

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

【问题讨论】:

    标签: java hibernate hbm2ddl


    【解决方案1】:

    配置属性名为hibernate.hbm2ddl.auto

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

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

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

    【讨论】:

    • 实际上,根据文档,create-drop 创建数据库表并在会话工厂显式关闭时删除它们。它不会在创建会话工厂时删除表。
    • 不,create-drop 和 create 在创建 sessionfactory 时都会删除表,然后 create-drop 也会在 sessionfactory 关闭时删除表。见stackoverflow.com/a/6752698/1536382
    • 在生产环境中制作 hibernate.hbm2ddl.auto=create-drop 会导致生产环境中的多次连接超时吗?
    【解决方案2】:

    我会使用liquibase 来更新您的数据库。 hibernate 的模式更新功能真的只是 o.k.对于开发新功能的开发人员来说。在生产环境中,需要更加小心地处理数据库升级。

    【讨论】:

    【解决方案3】:

    来自community documentation

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

    例如验证 |更新 |创建 |创建删除

    所以可能的选项列表是,

    • validate:验证架构,不更改数据库。
    • 更新:更新架构。
    • create:创建架构,销毁以前的数据。
    • create-drop:当 SessionFactory 显式关闭时删除模式,通常是在应用程序停止时。
    • none:对架构不做任何事情,不对数据库做任何更改

    这些选项似乎旨在成为开发人员工具,而不是促进任何生产级数据库,您可能想看看以下问题; Hibernate: hbm2ddl.auto=update in production?

    【讨论】:

    • 只需阅读休眠文档...对于有效值,它说:“例如” ...还有其他有效值吗?
    • 我认为它说的是“例如”因为它只是一个社区文档,如果有人对所有可能的值感兴趣,可以在 Hibernate 的 javadoc 中找到。 (是的,只有这四个选项存在)docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/cfg/…
    • validate 说验证架构,到底是什么意思??
    • 如果你想让hibernate什么都不做,你也可以使用'aardvark'、'pigeon'或任何其他词。我当然不会推荐!
    • 对 create-drop 选项的一个小补充。如果使用此选项,它不会删除整个架构,而是删除在运行此选项时映射可用的表。例如,如果一个带有 Schema S 的数据库有 A、B、C 表,而 java 代码只有 A 和 B 的映射,那么 Hibernate 不会删除表 C。
    【解决方案4】:

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

    【讨论】:

    • 这实际上非常有用,因为 Hibernate 的模式验证有时会因为完全有效的模式而失败。
    • 我正要问这样的事情。我的目的是减少启动时间。
    • 'empty string' 比 'none' 好。要使用“无”,您将收到警告消息:org.hibernate.cfg.SettingsFactory - “hibernate.hbm2ddl.auto”的无法识别值:无
    • 我已经修补了它。添加“none”作为明确有效的常量。
    • 我更喜欢“hibernate.hbm2ddl.auto=potato”stackoverflow.com/a/15810379/838444
    【解决方案5】:

    我认为你应该专注于

    SchemaExport Class 
    

    这个类使你的配置动态化 因此,它允许您选择最适合的套件...

    结帐[SchemaExport]

    【讨论】:

      【解决方案6】:

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

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

      如果您计划添加功能或执行一些自定义脚本,hibernate.hbm2ddl.auto="update" 很方便,但灵活性较差。

      所以,最灵活的方法是使用Flyway

      但是,即使您使用 Flyway,您仍然可以使用 hbm2ddl 生成初始迁移脚本。

      【讨论】:

      • drop 似乎不是一个有效的选项。你指的是哪个版本的休眠?
      • 自 2016 年发布的 Hibernate 5.1 以来,它一直是一个有效的选项。查看Action 枚举以获取更多详细信息。我假设您使用的是非常旧的 Hibernate 版本。
      • 验证与更新之间的确切区别是什么。
      • 答案说明差别。
      【解决方案7】:

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

      /**
       * 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";
      

      【讨论】:

      • 为什么引用超过 700 行长的源文件,上面有近 500 个 vole ups 的直接答案?
      • ...这个问题没有任何意义。为什么会有东西?我为什么会在这里?
      【解决方案8】:

      虽然这是一篇相当老的帖子,但由于我对该主题进行了一些研究,所以想分享它。

      hibernate.hbm2ddl.auto

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

      创建 |更新 |验证 |创建删除

      以下是对这些值所显示的行为的解释:

      • create :- 创建架构,架构中先前存在(如果存在)的数据将丢失
      • 更新:- 使用给定值更新架构。
      • validate:- 验证架构。它不会对数据库进行任何更改。
      • create-drop:- 创建架构并销毁先前存在的数据(如果存在)。当 SessionFactory 关闭时,它也会删除数据库架构。

      以下是值得注意的重点:

      • 更新的情况下,如果数据库中不存在架构,则创建架构。
      • validate 的情况下,如果数据库中不存在架构,则不会创建它。相反,它会抛出一个错误:- Table not found:&lt;table name&gt;
      • create-drop 的情况下,关闭会话时不会删除架构。它仅在关闭 SessionFactory 时下降。
      • 如果我给这个属性赋予任何值(比如 abc,而不是上面讨论的上述四个值)或者它只是留空。它显示以下行为:

        -如果数据库中不存在架构:- 它会创建架构

        -如果数据库中存在架构:- 更新架构。

      【讨论】:

      • 当schema不存在时,使用“update”时会创建schema,这确实是非常重要的一点。
      • create-drop 在比较“行为解释”和“重要点”语句时是矛盾的。
      • updateempty有什么区别?
      【解决方案9】:

      自 5.0 起,您现在可以在专用的 Enumorg.hibernate.boot.SchemaAutoTooling 中找到这些值(自 5.2 起使用值 NONE 进行了增强)。

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

      但是,你还不能用这个以编程方式配置DataSource。将它与org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO 结合使用会更好,但当前代码需要String 值(摘自SessionFactoryBuilderImpl):

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

      ... 和 org.hibernate.boot.SchemaAutoToolingorg.hibernate.tool.schema.Action 的内部 enum 值不会公开。

      在下面,一个示例程序化 DataSource 配置(用于我的 Spring Boot 应用程序)由于.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();
      }
      

      【讨论】:

        【解决方案10】:
        • validate:验证架构,数据库没有变化。
        • update:使用当前执行查询更新架构。
        • create:每次都会创建新的架构,并销毁以前的数据。
        • create-drop:当应用程序停止或 SessionFactory 显式关闭时删除架构。

        【讨论】:

        • 什么是“官方”文档参考? - 只是想知道......
        【解决方案11】:

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

        默认情况下,它不会在 DB 上自动执行任何创建或修改。如果用户设置以下值之一,则它会自动更改 DDL 架构。

        • create - 创建模式

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

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

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

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

        【讨论】:

        • 呢?
        【解决方案12】:

        validate:它验证架构并且不对数据库进行任何更改。
        假设您在映射文件中添加了一个新列并执行了插入操作,它将抛出一个异常“缺少 XYZ 列”,因为现有架构与您要插入的对象不同。如果您通过手动添加新列来更改表,然后执行插入操作,那么它肯定会将所有列与新列一起插入到表中。 意味着它不会对现有架构/表进行任何更改/更改。

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

        【讨论】:

          【解决方案13】:

          致寻找默认值的人...

          在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;
          

          【讨论】:

            【解决方案14】:

            综上所述... 注意这个属性叫做dll.auto,应该只控制dll操作(创建/删除模式/表),我惊讶地发现它也与dml有关:只有update允许插入数据,这是dml操作。

            在尝试将数据填充到内存数据库时被这个问题抓住了;只有update 有效。

            【讨论】:

              猜你喜欢
              • 2013-08-07
              • 2012-05-06
              • 2015-02-06
              • 2014-06-18
              • 2016-10-24
              • 2014-03-06
              • 1970-01-01
              • 2017-05-30
              相关资源
              最近更新 更多