java jpa自动建表 - Hibernate hbm2ddl.auto可能的值和他们做什么?




create none (12)

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

这些是可能发生在数据库上的变化:

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

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


Answers

配置属性称为hibernate.hbm2ddl.auto

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

理论上,您可以设置hibernate.hbm2ddl.auto=update来更新您的数据库,并对模型进行更改,但我不会相信生产数据库。 早期版本的文件表示这至少是实验性的; 我不知道目前的状况。

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


社区文档

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

例如验证| 更新| 创建| 创建降

所以可能的选项列表是,

  • 验证 :验证架构,不更改数据库。
  • 更新 :更新架构。
  • 创建 :创建模式,破坏以前的数据。
  • create-drop :在SessionFactory被显式关闭时,通常在应用程序停止时,删除模式。

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


还有“无”的无证价值完全禁用它。


理论上,您可以设置hibernate.hbm2ddl.auto = update来更新您的数据库,并对模型进行更改,但我不会相信生产数据库。 早期版本的文件表示这至少是实验性的; 我不知道目前的状况。

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


我认为你应该集中注意力

SchemaExport Class 

这个类使你的配置变得动态所以它允许你选择你最适合的套房......

结帐[SchemaExport]


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">
    

如果你不想在你的应用中使用字符串,并且正在寻找预定义的常量,那么可以看一下包含在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";

我专门为最常见的Hibernate DDL生成策略撰写 博客文章

  1. 如果您计划添加函数或执行一些自定义脚本, hibernate.hbm2ddl.auto="update"方便但灵活性较低。
  2. 最灵活的方法是使用Flyway

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


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

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


验证:验证架构,不会发生数据库更改。 更新:用当前执行的查询更新模式。 创建:每次创建新的模式,并销毁以前的数据。 create-drop:在应用程序停止或显式关闭SessionFactory时删除架构。


从5.0开始 ,您现在可以在专用Enum找到这些值: org.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()函数使用gambit,但只适用于没有破折号的值(例如不是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();
}

没有NullPointerException的清洁解决方案是:

map.replace(key, map.get(key) + 1);




java hibernate hbm2ddl