我真的想更多地了解更新,导出以及可以提供的值,hibernate.hbm2ddl.auto
我需要知道何时使用更新,何时不使用更新?还有什么选择?
这些是可能在数据库上发生的更改:
- 新表
- 旧表中的新列
- 列已删除
- 列的数据类型已更改
- 列的类型更改了其属性
- 桌子掉了
- 列的值已更改
在每种情况下,最佳解决方案是什么?
我真的想更多地了解更新,导出以及可以提供的值,hibernate.hbm2ddl.auto
我需要知道何时使用更新,何时不使用更新?还有什么选择?
这些是可能在数据库上发生的更改:
在每种情况下,最佳解决方案是什么?
Answers:
从社区文档:
hibernate.hbm2ddl.auto创建SessionFactory时,自动将模式DDL验证或导出到数据库。使用create-drop时,显式关闭SessionFactory时将删除数据库架构。
例如验证| 更新| 创建| 创建放置
因此,可能的选项列表是
这些选项似乎旨在作为开发人员的工具,而不是为了促进任何生产级别的数据库,您可能需要查看以下问题;休眠:hbm2ddl.auto =正在生产中更新?
还有一个未记录的值“ none”可以完全禁用它。
配置属性称为 hibernate.hbm2ddl.auto
在我们的开发环境中,我们设置hibernate.hbm2ddl.auto=create-drop
为每次部署时都删除并创建一个干净的数据库,以使数据库处于已知状态。
从理论上讲,您可以设置hibernate.hbm2ddl.auto=update
使用模型更改来更新数据库,但是我不相信在生产数据库上这样做。该文档的早期版本说,这至少是试验性的;我不知道目前的状态。
因此,对于我们的生产数据库,请勿设置hibernate.hbm2ddl.auto
-默认为不更改数据库。相反,我们手动创建一个SQL DDL更新脚本,该脚本将更改从一个版本应用到下一个版本。
我会使用liquibase更新您的数据库。对于开发人员开发新功能时,hibernate的架构更新功能确实是可行的。在生产情况下,需要更仔细地处理数据库升级。
尽管这是一篇很老的文章,但是由于我对此主题进行了一些研究,所以想分享它。
hibernate.hbm2ddl.auto
根据文档,它可以具有四个有效值:
创建| 更新| 验证| 创建放置
以下是这些值显示的行为的说明:
以下是值得注意的要点:
Table not found:<table name>
如果我给此属性提供任何值(例如abc,而不是上面讨论的上述四个值),或者它留为空白。它显示以下行为:
-如果数据库中不存在模式:-它创建模式
-如果数据库中存在模式:- 更新模式。
首先,hbm2ddl
配置属性的可能值为以下值:
none
-不执行任何操作。该架构将不会生成。create-only
-将生成数据库模式。drop
-之后将删除并创建数据库模式。create
-之后将删除并创建数据库模式。create-drop
-之后将删除并创建数据库模式。关闭时SessionFactory
,数据库架构将被删除。validate
-将使用实体映射来验证数据库模式。update
-通过将现有数据库架构与实体映射进行比较来更新数据库架构。我在博客文章中介绍了最常见的Hibernate DDL生成策略:
hibernate.hbm2ddl.auto="update"
如果您打算添加功能或执行一些自定义脚本,则方便但不灵活。但是,即使使用Flyway,仍然可以使用hbm2ddl生成初始迁移脚本。在本文中,您将看到如何将JPA实体模型与jOOQ表模型结合起来。
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">
如果您不想在应用程序中使用字符串,并且正在寻找预定义的常量,请查看org.hibernate.cfg.AvailableSettings
Hibernate 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";
validate
:验证架构,数据库没有任何变化。update
:使用当前的执行查询更新架构。create
:每次创建新的架构,并销毁先前的数据。create-drop
:在停止应用程序或显式关闭SessionFactory时删除架构。validate
:它将验证模式,并且不对数据库进行任何更改。
假设您已在映射文件中添加了新列并执行插入操作,由于现有架构与您要插入的对象不同,它将引发异常“缺少XYZ列”。如果您通过手动添加新列来更改表,然后执行插入操作,则它将肯定会将所有列以及新列插入到表中。意味着它不会对现有的架构/表进行任何更改/更改。
update
:执行操作时,它将更改数据库中的现有表。您可以使用hbm2ddl选项添加或删除列。但是,如果要添加“ NOT NULL”的新列,则它将忽略将特定列添加到数据库。因为如果要向现有表添加“ NOT NULL”列,则表必须为空。
从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.SchemaAutoTooling
并org.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();
}
向谁搜索默认值...
它使用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;