ChatGPT解决这个技术问题 Extra ChatGPT

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

我真的很想了解有关更新、导出和可以赋予 hibernate.hbm2ddl.auto
的值的更多信息。我需要知道什么时候使用更新,什么时候不使用?什么是替代方案?

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

新表

旧表中的新列

已删除的列

列的数据类型已更改

一种类型的列改变了它的属性

表被丢弃

列的值已更改

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


C
Community

community documentation

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

所以可能的选项列表是,

validate:验证模式,不更改数据库。

更新:更新架构。

create:创建模式,销毁以前的数据。

create-drop:当 SessionFactory 显式关闭时删除模式,通常是在应用程序停止时。

none:对模式不做任何事情,不对数据库做任何更改

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


只需阅读休眠文档...对于有效值,它会说:“例如”...还有其他有效值吗?
我认为它说“eg”是因为它只是一个社区文档,如果有人对所有可能的值感兴趣,可以在 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。
M
Michiel Verkaik

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


这实际上非常有用,因为 Hibernate 的模式验证有时会因为完全有效的模式而失败。
我正要问这样的事情。我的目的是减少启动时间。
“空字符串”比“无”好。要使用“无”,您将收到警告消息:org.hibernate.cfg.SettingsFactory - “hibernate.hbm2ddl.auto”的无法识别值:无
我已经修补了它。添加“无”作为明确有效的常量。
我喜欢“hibernate.hbm2ddl.auto=potato”而不是其他人stackoverflow.com/a/15810379/838444
P
Peter Hilton

配置属性称为 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 会导致生产中的多个连接超时吗?
V
Vlad Mihalcea

首先,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 版本。
验证与更新之间的确切区别是什么。
答案说明了区别。
P
Pat

我会使用 liquibase 来更新您的数据库。 hibernate 的模式更新功能实际上只适用于开发新功能的开发人员。在生产情况下,需要更加小心地处理数据库升级。


请参阅 stackoverflow.com/questions/221379/…,了解为什么不应将 hbm2ddl 用于生产。
a
amit

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

休眠.hbm2ddl.auto

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

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

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

create :- 创建模式,模式中先前存在的数据(如果存在)将丢失

更新:- 使用给定值更新架构。

验证:- 验证架构。它在数据库中没有任何变化。

create-drop:- 创建模式并销毁先前存在的数据(如果存在)。当 SessionFactory 关闭时,它也会删除数据库模式。

以下是值得注意的要点:

在更新的情况下,如果数据库中不存在架构,则创建架构。

在验证的情况下,如果数据库中不存在架构,则不会创建它。相反,它会抛出一个错误:- 找不到表:<表名>

在 create-drop 的情况下,关闭会话时不会删除模式。它仅在关闭 SessionFactory 时下降。

如果我给这个属性任何值(比如 abc,而不是上面讨论的四个值),或者它只是留空。它显示以下行为: - 如果数据库中不存在架构:- 它创建架构 - 如果数据库中存在架构:- 更新架构。


当使用“更新”时,如果模式不存在,将创建模式确实是非常重要的一点。
比较“行为解释”和“重要点”语句时,create-drop 是矛盾的。
update 和 empty 有什么区别?
T
Tom

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

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

create - 创建模式

update - 更新现有模式

validate - 验证现有模式

create-drop - 在会话开始和结束时自动创建和删除模式


呢?
S
Stefan Haberl

如果您不想在应用程序中使用字符串并且正在寻找预定义的常量,请查看 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 个 vol ups?
...这个问题没有任何意义。为什么会有东西?为什么我什至在这里?
R
Ravi K M

validate:验证模式,数据库没有变化。

更新:使用当前执行查询更新架构。

create:每次创建新的模式,并销毁以前的数据。

create-drop:当应用程序停止或 SessionFactory 显式关闭时删除模式。


什么是“官方”文档参考? - 就是想...
V
Vishal Sharma

我认为你应该专注于

SchemaExport Class 

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

结帐 [SchemaExport]


A
Arun Raaj

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

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


D
Doc Davluz

自 5.0 起,您现在可以在专用的 Enum 中找到这些值:org.hibernate.boot.SchemaAutoTooling(自 5.2 起使用值 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 ) );

... 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();
}

C
Chaya Shetty

对于搜索默认值的任何人...

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

W
WesternGun

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

尝试将数据填充到内存数据库中时被此抓住;只有 update 有效。