是否可以运行配置了hbm2ddl的Hibernate应用程序。自动=update在生产环境中更新数据库模式?
当前回答
我同意弗拉基米尔的观点。如果我提出这样的课程,我公司的管理人员肯定不会感激。
此外,创建SQL脚本而不是盲目地信任Hibernate,使您有机会删除不再使用的字段。Hibernate不会这样做。
我发现,比较生产模式和新模式可以让您更好地了解数据模型中所更改的内容。当然,你知道,因为你成功了,但现在你看到所有的变化一气呵成。即使是那些让你想“搞什么鬼?!”
有一些工具可以为您创建模式增量,因此这甚至不是一项艰巨的工作。然后你就知道会发生什么了。
其他回答
Hibernate必须在prod中声明不使用自动更新,以在不应该使用prod的情况下,当不知道自己在做什么的人使用它时,Hibernate可以保护自己。
当然,不应该使用的情况远远超过可以使用的情况。
我已经在许多不同的项目中使用它很多年了,从来没有出现过一个问题。这不是一个蹩脚的答案,也不是牛仔编码。这是历史事实。
一个人说“永远不要在生产中这样做”,他想到的是一组特定的生产部署,即他所熟悉的(他的公司,他的行业等)。
“生产部署”的范围是巨大而多样的。
有经验的Hibernate开发人员确切地知道给定映射配置将产生什么DDL。只要您测试并验证您期望的内容最终出现在DDL中(在开发、qa、登台等),就没问题。
在添加大量特性时,自动模式更新可以真正节省时间。
自动更新不能处理的事情是无穷无尽的,但一些例子是数据迁移,添加非空列,列名更改,等等。
此外,您还需要注意集群环境。
但话说回来,如果你知道这些,你就不会问这个问题了。嗯……好的,如果您正在问这个问题,那么在考虑在prod中使用它之前,您应该等到对Hibernate和自动模式更新有了丰富的经验。
应用程序的模式可能会随着时间而变化;如果您有多个安装,可能是不同的版本,您应该有某种方法来确保您的应用程序、某种工具或脚本能够逐步将模式和数据从一个版本迁移到下一个版本。
将所有持久性放在Hibernate映射(或注释)中是控制模式演变的一种非常好的方法。
您应该考虑模式演化有几个方面需要考虑:
数据库模式的演变 添加更多的列和表 删除旧的列,表和 关系 用默认值填充新列
Hibernate工具非常重要,特别是当你在许多不同类型的数据库上有相同应用程序的不同版本时(就像我的经验一样)。
第3点在使用Hibernate时非常敏感,例如在引入一个新的布尔值属性或数值属性时,如果Hibernate在这些列中发现任何空值,则会引发异常。
所以我要做的是:确实使用Hibernate工具的模式更新功能,但必须在它旁边添加一些数据和模式维护回调,比如填充默认值,删除不再使用的列,等等。通过这种方式,您获得了优势(独立于数据库的模式更新脚本和避免在持久性和脚本中对更新进行重复编码),但也涵盖了操作的所有方面。
因此,例如,如果版本更新只是添加一个varchar值属性(即列),它可能默认为null,那么使用自动更新就可以完成。在需要更复杂的地方,就需要做更多的工作。
这是假设更新时的应用程序能够更新其模式(这是可以做到的),这也意味着它必须拥有对模式进行更新的用户权限。如果客户的策略阻止了这一点(可能是Lizard Brain的情况),您将不得不提供特定于数据库的脚本。
Hibernate创建者在他们的书“Java Persistence with Hibernate”中不鼓励在生产环境中这样做:
警告:我们已经看到Hibernate用户试图使用SchemaUpdate自动更新生产数据库的模式。这很快就会导致灾难,而且DBA不允许这样做。
使用hbm2ddl不是一个好主意。汽车生产。
管理数据库模式的唯一方法是使用增量迁移脚本,因为:
脚本将与你的代码库一起驻留在VCS中。签出分支时,从头重新创建整个模式。 增量脚本在应用到生产环境之前可以在QA服务器上进行测试 不需要手动干预,因为脚本可以通过Flyway运行,因此它减少了与手动运行脚本相关的人为错误的可能性。
甚至Hibernate用户指南也建议您避免在生产环境中使用hbm2ddl工具。
通常,大型组织中的企业应用程序以较少的权限运行。 数据库用户名可能没有DDL权限,不能添加hbm2ddl的列。汽车=更新要求。
推荐文章
- 转换列表的最佳方法:map还是foreach?
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?
- 为什么Java流是一次性的?
- 四舍五入BigDecimal *总是*有两位小数点后
- 设计模式:工厂vs工厂方法vs抽象工厂
- Java:检查enum是否包含给定的字符串?