spring.jpa.hibernate.ddl-auto 属性在 Spring 中是如何工作的?

Posted

技术标签:

【中文标题】spring.jpa.hibernate.ddl-auto 属性在 Spring 中是如何工作的?【英文标题】:How does spring.jpa.hibernate.ddl-auto property exactly work in Spring? 【发布时间】:2017-06-27 08:51:29 【问题描述】:

我正在开发我的 Spring Boot 应用程序项目,并注意到,有时我的另一台服务器 (SQL Server) 上的数据库会出现连接超时错误。 当我尝试使用FlyWay 进行一些脚本迁移时会特别发生这种情况,但经过多次尝试后它仍然有效。

然后我注意到我没有在属性文件中指定spring.jpa.hibernate.ddl-auto。我做了一些研究,发现建议添加 spring.jpa.hibernate.ddl-auto= create-drop 正在开发中。 并将其更改为:spring.jpa.hibernate.ddl-auto= none 在生产中。

但我实际上并不了解它是如何工作的,以及 hibernate 如何使用create-dropnone 值生成数据库模式。您能否从技术上解释它是如何工作的,以及在开发和生产服务器上使用此属性的建议是什么。 谢谢

【问题讨论】:

FWIW JPA 2.1 有一个 standard 属性 javax.persistence.schema-generation.database.action 所以真的不需要使用 JPA 供应商特定的属性来生成模式. @NeilStockton 我们正在使用 Hibernate 6 探索的一个想法是能够根据类别以不同方式控制模式生成。例如您的 orm 表可能是 none,但您可能希望使用 update 生成 Hibernate Search 和 Envers 表,因为它们由这些项目在内部管理,而您不想自己手动管理它们。现在,我们对所有表进行全局控制,无论它们的来源/来源如何。如果您想使用它,这将进一步说明使用供应商特定选项的原因。 这个属性是一种指定hibernate为数据库应用DDL的方法。它是特定于休眠的。更多详情springhow.com/spring-boot-database-initialization 【参考方案1】:

“spring.jpa.hibernate.ddl-auto=create-drop”表示在服务器运行时,创建数据库(表)实例。并且每当服务器停止时,数据库表实例就会被删除。

【讨论】:

【参考方案2】:

在 Spring/Spring-Boot 中,SQL 数据库可以根据您的堆栈以不同的方式初始化。

JPA 具有生成 DDL 的功能,这些功能可以设置为在启动时针对数据库运行。这是通过两个外部属性控制的:

spring.jpa.generate-ddl(布尔值)打开和关闭该功能,并且独立于供应商。 spring.jpa.hibernate.ddl-auto (enum) 是一个 Hibernate 特性,它以更细粒度的方式控制行为。有关详细信息,请参见下文。

Hibernate 属性值为:create、update、create-drop、validate 和 none:

create - Hibernate 首先删除现有表,然后创建新表 update – 将基于映射(注解或 XML)创建的对象模型与现有模式进行比较,然后 Hibernate 根据差异更新模式。即使应用程序不再需要现有的表或列,它也不会删除它们 create-drop – 类似于 create,除了所有操作完成后 Hibernate 将删除数据库。通常用于单元测试 validate - Hibernate 只验证表和列是否存在,否则抛出异常 none - 此值有效地关闭 DDL 生成

如果未检测到模式管理器,则 Spring Boot 内部默认此参数值为 create-drop,否则对于所有其他情况都没有。

【讨论】:

【参考方案3】:

作为记录,spring.jpa.hibernate.ddl-auto 属性是 Spring Data JPA 特定的,并且是他们指定一个值的方式,该值最终将在它知道的属性 hibernate.hbm2ddl.auto 下传递给 Hibernate。

createcreate-dropvalidateupdate 值基本上会影响架构工具管理在启动时将如何操作数据库架构。

例如,update 操作将查询 JDBC 驱动程序的 API 以获取数据库元数据,然后 Hibernate 将根据读取您的带注释的类或 HBM XML 映射来比较它创建的对象模型,并尝试调整架构 -苍蝇。

例如,update 操作将尝试添加新列、约束等,但绝不会删除以前可能存在但不再作为先前运行的对象模型的一部分的列或约束。

通常在测试用例场景中,您可能会使用create-drop,以便创建架构、测试用例添加一些模拟数据、运行测试,然后在测试用例清理期间删除架构对象,留下一个空数据库。

在开发中,经常看到开发人员使用update 自动修改架构以在重启时添加新内容。但请再次理解,这不会删除之前执行中可能存在的不再需要的列或约束。

在生产中,通常强烈建议您使用none 或干脆不指定此属性。这是因为 DBA 通常会检查迁移脚本以了解数据库更改,尤其是当您的数据库在多个服务和应用程序之间共享时。

【讨论】:

是的,永远不要在生产中使用 ddl 生成。我们使用 ddl 为表结构生成初始脚本,并让 DBA 参与其中。然后,我们将 db 脚本作为部署单元的一部分包含在内,并在部署应用程序时使用 Flyway 执行它们。当我们需要修改数据库时,我们将新脚本添加到应用程序的下一个版本并部署到 staging。 Flyway 将自动检测当前版本并运行将数据库更新到最新版本所需的脚本。如果一切正常,我们将部署到生产环境。 如果我们不指定这个属性怎么办?例如我有我自己的 ... update 我有这个并且由于某种原因,我的桌子总是被丢弃,直到我添加了上述属性;; ps:对不起代码示例) 为什么不在生产环境中使用validate @ShamalKarunarathne 应用程序可以在生产中使用validate,但通常这应该是您在质量/测试环境中使用的设置,以验证您已编写或应用于数据库迁移的数据库脚本工具准确。在生产环境中不使用validate 的另一个原因是,它可能会成为应用程序启动过程中的瓶颈,尤其是当您的对象模型规模非常庞大或其他网络相关因素发挥作用时。 没有精确的堆栈跟踪很难推测;但是,我的第一个猜测是 order 被 SQL 解析器错误地解释了,因为如果它没有被转义,那它就是一个关键字。

以上是关于spring.jpa.hibernate.ddl-auto 属性在 Spring 中是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

当为 Postgres DB 的属性 spring.jpa.hibernate.ddl-auto 提供更新值时,Hibernate 不会生成序列

spring.jpa.hibernate.ddl-auto 属性在 Spring 中是如何工作的?

spring.jpa.hibernate.ddl-auto=validate 或更新返回 beans.factory.BeanCreationException

spring.jpa.hibernate.ddl-auto=create 在带有 SpringBoot 2.0 的 Hibernate 5 中不起作用

Spring Boot ddl 自动生成器

spring-boot Jpa配置