Hibernate hbm2ddl.auto可能的值和他们做什么?
我真的想知道更多关于更新,导出和值可以给hibernate.hbm2ddl.auto
我需要知道何时使用更新,什么时候不使用? 还有什么替代方法?
这些是可能发生在DB上的变化:
- 新表格
- 旧表中的新列
- 列删除
- 数据types的列已更改
- 一个列的types改变了它的属性
- 表已经被删除
- 列的值已更改
在每种情况下,最好的解决scheme是什么?
从社区文档 :
hibernate.hbm2ddl.auto创buildSessionFactory时自动validation或导出模式DDL到数据库。 使用create-drop,当SessionFactory被显式closures时,数据库模式将被删除。
例如validation| 更新| 创build| 创build降
所以可能的选项列表是,
- validation :validation模式,不更改数据库。
- 更新 :更新架构。
- 创build :创build模式,销毁以前的数据。
- create-drop :在SessionFactory被明确closures时(通常是在应用程序停止时),删除模式。
这些选项似乎是为了成为开发人员的工具而不是为了方便任何生产级别的数据库,您可能需要查看以下问题; hibernate:hbm2ddl.auto =生产中更新?
还有“无”的无证价值完全禁用它。
configuration属性被称为hibernate.hbm2ddl.auto
在我们的开发环境中,我们将hibernate.hbm2ddl.auto=create-drop
为drop,并在每次部署时创build一个干净的数据库,以便我们的数据库处于已知状态。
从理论上讲,你可以设置hibernate.hbm2ddl.auto=update
来更新你的模型,但是我不会相信生产数据库。 早期版本的文件表示这至less是实验性的; 我不知道目前的状况。
因此,对于我们的生产数据库,不要设置hibernate.hbm2ddl.auto
– 缺省情况是不做数据库更改。 相反,我们手动创build一个SQL DDL更新脚本,将更改从一个版本应用到下一个版本。
我会使用liquibase更新你的数据库。 在开发新function的时候,hibernate的模式更新function对于开发人员来说确实不错。 在生产环境中,数据库升级需要更仔细地处理。
虽然这是一个相当古老的职位,但我做了一些关于这个主题的研究,所以想到分享它。
hibernate.hbm2ddl.auto
根据文档,它可以有四个有效的值:
创build| 更新| validation| 创build降
以下是对这些值所显示的行为的解释:
- 创build : – 创build模式,模式中先前存在的数据(如果有的话)丢失
- 更新: – 用给定的值更新模式。
- validation: – validation架构。 它没有改变数据库。
- 创build – 删除: – 创build模式与销毁以前存在的数据(如果有的话)。 它还会在SessionFactoryclosures时删除数据库模式。
以下是值得注意的重点:
- 在更新的情况下,如果数据库中不存在模式,则创build模式。
- 在validation的情况下,如果数据库中不存在架构,则不会创build该架构。 相反,它会抛出一个错误: –
Table not found:<table name>
- 在创build – 删除的情况下,架构在closures会话时不会丢失。 它只会在closuresSessionFactory时下降。
-
如果我给这个属性有任何价值(比如abc,而不是上面讨论的四个以上的值),或者只是留空。 它显示以下行为:
– 如果模式不存在于数据库中: – 它创build模式
– 如果模式存在于数据库中: – 更新模式。
如果你不想在你的应用程序中使用string,并且正在寻找预定义的常量,那么可以看一下包含在Hibernate JAR中的org.hibernate.cfg.AvailableSettings
类,在这里你可以find所有可能的设置的常量。 以你的情况为例:
/** * 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生成策略撰写 博客文章 :
- 如果您计划添加函数或执行一些自定义脚本,
hibernate.hbm2ddl.auto="update"
方便但不太灵活。 - 最灵活的方法是使用
org.hibernate.tool.ant.HibernateToolTask
生成DDL脚本,然后使用组件在上下文启动时执行脚本。 当Spring上下文closures时,销毁脚本被调用。
第二种方法更加灵活,特别是如果您想要将JPA实体模型与jOOQ表模型混合在一起。
不用说,这只是一个集成testing问题,因为在生产环境中我们使用了Flyway 。
hibernate.hbm2ddl.auto
会在创buildsessionFactory时自动validation并将DDL导出到模式。
默认情况下,它不会自动在数据库上执行任何创build或修改。 如果用户设置下面的值之一,那么它自动执行DDL模式更改。
-
创build – 创build模式
<entry key="hibernate.hbm2ddl.auto" value="create">
-
更新 – 更新现有的模式
<entry key="hibernate.hbm2ddl.auto" value="update">
-
validation – validation现有的模式
<entry key="hibernate.hbm2ddl.auto" value="validate">
-
create-drop – 在会话开始和结束时自动创build和删除模式
<entry key="hibernate.hbm2ddl.auto" value="create-drop">
我认为你应该专心于
SchemaExport Class
这个class让你的configurationdynamic所以它可以让你select你最好的任何套房…
结帐[SchemaExport]
从5.0开始 ,您现在可以在专用的Enum
: org.hibernate.boot.SchemaAutoTooling
find这些值(自5.2开始,值为NONE
增强)。
或者更好, 从5.1开始 ,还可以使用org.hibernate.tool.schema.Action
Enum
,它将JPA 2和“传统”Hibernate DDL操作相结合。
但是 ,你不能用这个编程方式configuration一个DataSource
。 使用org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO
会更好,但是当前的代码需要一个String
值(摘自SessionFactoryBuilderImpl
):
this.schemaAutoTooling = SchemaAutoTooling.interpret( (String) configurationSettings.get( AvailableSettings.HBM2DDL_AUTO ) );
… org.hibernate.boot.SchemaAutoTooling
和org.hibernate.tool.schema.Action
内部enum
值不公开公开。
下面是一个示例程序化DataSource
configuration(在我的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(); }
validation:validation模式,不要改变数据库。 更新:用当前执行的查询更新模式。 创build:每次创build新的模式,并销毁以前的数据。 create-drop:在应用程序停止或显式closuresSessionFactory时删除模式。
validate
:它validation模式并且不更改数据库。
假设您在映射文件中添加了一个新列并执行插入操作,则会抛出一个“丢失XYZ列”exception,因为现有的模式与您要插入的对象不同。 如果您通过手动添加新列来更改表,然后执行插入操作,那么肯定会将所有列与新列一起插入到表中。 意味着它不做任何改变/改变现有的模式/表格。
update
:当您执行操作时,它会更改数据库中的现有表。 您可以使用hbm2ddl的此选项添加或删除列。 但是,如果要添加一个“NOT NULL”的新列,那么它将忽略将该特定列添加到数据库。 因为如果要将“NOT NULL”列添加到现有表中,该表必须为空。
从理论上讲,你可以设置hibernate.hbm2ddl.auto = update来更新你的模型,但是我不会相信生产数据库。 早期版本的文件表示这至less是实验性的; 我不知道目前的状况。
因此,对于我们的生产数据库,不要设置hibernate.hbm2ddl.auto – 缺省情况是不做数据库更改。 相反,我们手动创build一个SQL DDL更新脚本,将更改从一个版本应用到下一个版本。