当前位置:  开发笔记 > 编程语言 > 正文

Hibernate:hbm2ddl.auto =在生产中更新?

如何解决《Hibernate:hbm2ddl.auto=在生产中更新?》经验,为你挑选了11个好方法。

是否可以运行配置的Hibernate应用程序hbm2ddl.auto=update来更新生产环境中的数据库模式?



1> Vladimir Dyu..:

不,这不安全.

尽管Hibernate团队做出了最大努力,但您根本无法依靠生产中的自动更新.编写自己的补丁,使用DBA进行检查,测试它们,然后手动应用它们.

从理论上讲,如果hbm2ddl update在开发中有效,它也应该在生产中工作.但实际上,并非总是如此.

即使它工作正常,也可能是次优的.DBA因为某种原因得到了很多报酬.


这是不安全的,因为应用的补丁可能具有hbm2ddl几乎无法预测的副作用(例如禁用为正在修改的表安装的触发器).对于复杂的模式,最安全的方法是手动.自动进行回归后测试是遥远的第二步.所有恕我直言.
为什么不安全?
Fwiw,目前Hibernate的架构更新不会删除表或列.
此外,更新数据库模式应由专业人员(dbas)处理.从糟糕的数据库更改中恢复很困难.Vova没有提到它 - 但是如果hibernate的更新决定放弃一个列并重新添加它,因为类型或大小发生了变化,会发生什么.我们可以说该列是您的所有用户电子邮件地址吗?:-)再见,再见公司.....你想要自动生成DDL变化 - 但你绝对希望人类检查变更.
你不升级前备份数据库吗?
没有.只是不要使用此选项.
恢复企业级数据是一个巨大的痛苦.现在想象一下你发现一周后Hib Update会引入一个问题?最好花一点时间让DBA小心翼翼地做出改变,而不是浪费几个班次(如果不是几天)试图将备份带回来并保留以后的更新......

2> Brian Deterl..:

我们在生产中实现这一点,尽管应用程序不是关键任务,并且员工没有高薪DBA.它只是一个人为错误的手动过程 - 应用程序可以检测到差异并做正确的事情,而且您可能已经在各种开发和测试环境中对其进行了测试.

一个警告 - 在集群环境中,您可能希望避免它,因为多个应用程序可以同时出现并尝试修改可能不好的架构.或者放入一些只允许一个实例更新架构的机制.


我们也在类似的用例中在生产中使用它。不是关键任务的分析平台。我们已经在4个环境(4年)中部署了16K次,而不会因休眠而造成太多麻烦。我们是一个小团队,都是SQL RDBS的初学者,与我们自己相比,他们对Hibernate处理架构有更好的信念。我想知道让DBA负责人员管理迁移和架构更改的错误率是多少?在〜16K部署中,它是否比0好?

3> Roman..:

Hibernate创建者不鼓励在他们的书"Java Persistence with Hibernate"中的生产环境中这样做:

警告:我们已经看到Hibernate用户尝试使用SchemaUpdate自动更新生产数据库的模式.这很快就会以灾难告终,您的DBA将不允许这样做.



4> jpswain..:

查看LiquiBase XML以保留更新的更新日志.我从来没有使用它,直到今年,但我发现它很容易学习,并使数据库修订控制/迁移/变更管理非常万无一失.我在Groovy/Grails项目上工作,Grails在其下面使用Hibernate来创建所有ORM(称为"GORM").我们使用Liquibase来管理所有SQL架构更改,当我们的应用程序随新功能发展时,我们会经常这样做.

基本上,您保留一个变更集的XML文件,您可以随着应用程序的发展继续添加这些变量集.这个文件与你的项目的其余部分一起保存在git(或者你正在使用的任何东西)中.部署应用程序时,Liquibase会检查您要连接的数据库中的更改日志表,以便知道已经应用了什么,然后智能地应用文件中尚未应用的任何更改集.它在实践中非常有用,如果您将它用于所有架构更改,那么您可以100%确信您签出和部署的代码始终能够连接到完全兼容的数据库架构.

令人敬畏的是,我可以在笔记本电脑上使用一个完全空白的slate mysql数据库,启动应用程序,然后立即为我设置架构.它还可以通过首先将这些更改应用于local-dev或staging db来轻松测试模式更改.

开始使用它的最简单方法可能是获取现有数据库,然后使用Liquibase生成初始baseline.xml文件.然后在将来,您可以添加到它并让liquibase接管管理架构更改.

http://www.liquibase.org/



5> cliff.meyers..:

我会投票否决.当列的数据类型发生更改时,Hibernate似乎不理解.示例(使用MySQL):

String with @Column(length=50)  ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)

@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed

可能还有其他示例,例如将String列的长度超过255并将其转换为text,mediumtext等.

当然,我认为没有真正的方法可以在不创建新列的情况下"转换数据类型",复制数据并吹掉旧列.但是,当您的数据库具有不反映当前Hibernate映射的列时,您生活得非常危险......

Flyway是处理这个问题的好方法:

http://flywaydb.org



6> john.stein..:

Hibernate必须放弃关于不使用自动更新的免责声明,以便当不知道他们正在做什么的人在不应该使用它的情况下使用它时自己覆盖.

在不应该使用的情况下,可以大大超过那些可以使用的情况.

我已经在很多不同的项目上使用它多年,从来没有遇到过一个问题.这不是一个蹩脚的答案,而不是牛仔编码.这是一个历史事实.

一个说"从不在生产中做"的人正在考虑一组特定的生产部署,即他熟悉的那些(他的公司,他的行业等).

"生产部署"的范围广泛而多样.

经验丰富的Hibernate开发人员确切知道DDL将从给定的映射配置中产生什么.只要你测试并验证你期望在DDL中的内容(在dev,qa,staging等中),你就可以了.

当您添加许多功能时,自动架构更新可以节省大量时间.

自动更新无法处理的内容列表是无穷无尽的,但一些示例是数据迁移,添加不可为空的列,列名称更改等.

您还需要在群集环境中小心.

但话说回来,如果你知道所有这些东西,你就不会问这个问题了.嗯...好的,如果你问这个问题,你应该等到你有很多Hibernate和自动架构更新的经验,然后才考虑在prod中使用它.



7> Vlad Mihalce..:

正如我在本文中所解释的那样,hbm2ddl.auto在生产中使用它并不是一个好主意.

管理数据库模式的唯一方法是使用增量迁移脚本,因为:

脚本将沿着代码库驻留在VCS中.签出分支时,从头开始重新创建整个架构.

增量脚本可以在生产中应用之前在QA服务器上进行测试

因为脚本可以由Flyway运行,所以不需要手动干预,因此它减少了与手动运行脚本相关的人为错误的可能性.

即使是" Hibernate用户指南"也建议您避免在hbm2ddl生产环境中使用该工具.

在此输入图像描述



8> Jaap Coomans..:

我不会冒险,因为你最终可能会丢失应该保留的数据.hbm2ddl.auto = update纯粹是一种让您的dev数据库保持最新的简单方法.


是的,我当然可以,但从备份中恢复需要做很多工作.当您还可以有序地更新数据库时,恢复备份的麻烦是不值得的.
升级之前不备份数据库吗?

9> 小智..:

我们在一个项目中运行了几个月,到目前为止从未出现过问题.请记住此配方所需的2种成分:

    使用向后兼容性方法设计对象模型,即弃用对象和属性,而不是删除/更改它们.这意味着如果您需要更改对象或属性的名称,请保留原有的名称,添加新的名称并编写某种迁移脚本.如果您需要更改对象之间的关联,如果您已经在生产中,这意味着您的设计首先是错误的,因此请尝试考虑一种表达新关系的新方式,而不会影响旧数据.

    始终在部署之前备份数据库.

我的感觉是 - 在阅读这篇文章后 - 参与讨论的人中有90%只是想到在生产环境中使用这样的自动化.有些人把球扔到了DBA.花一点时间考虑并非所有生产环境都会提供DBA,并且没有多少开发团队能够负担得起(至少对于中等规模的项目).所以,如果我们谈论的是每个人都必须做所有事情的球队,球就在他们身上.

在这种情况下,为什么不尝试两全其美?像这样的工具可以提供帮助,通过精心的设计和计划,可以在许多情况下提供帮助.相信我,管理员最初可能很难说服,但如果他们知道球不在他们手上,他们就会喜欢它.

就个人而言,我永远不会再手工编写脚本来扩展任何类型的架构,但这只是我的意见.在最近开始采用NoSQL无架构数据库之后,我可以看到,所有这些基于模式的操作都将属于过去,因此您最好开始改变您的观点并展望未来.


我不同意NoSQL评论.它肯定正在崛起并且有它的位置,但是有许多应用程序绝对依赖于ACID合规性,以及NoSQL无法提供的并发和事务的数据完整性.

10> 小智..:

在我的例子中(Hibernate 3.5.2,Postgresql,Ubuntu),设置hibernate.hbm2ddl.auto=update只创建新表并在现有表中创建新列.

它既没有删除表,也没有删除列,也没有改变列.它可以被称为安全选项,但类似的东西hibernate.hbm2ddl.auto=create_tables add_columns会更清楚.



11> Dherik..:

这不安全,不建议使用,但是有可能。

我在生产中使用自动更新选项的应用程序中有经验。

好了,此解决方案中发现的主要问题和风险是:

部署在错误的数据库中。如果您犯了使用错误版本数据库中的旧版本应用程序(EAR / WAR / etc)运行应用程序服务器的错误,您将拥有许多新的列,表,外键和错误。数据源文件(复制/粘贴文件,忘记更改数据库)中的简单错误也可能发生相同的问题。在简历中,这种情况可能是数据库中的灾难。

应用程序服务器启动时间太长。发生这种情况是因为每次启动应用程序时,Hibernate都会尝试查找所有已创建的表/列/等。他需要知道需要创建什么(表,列等)。随着数据库表的增长,这个问题只会变得更糟。

数据库工具几乎是不可能使用的。要创建数据库DDL或DML脚本以在新版本上运行,您需要考虑启动应用程序服务器后自动更新将创建的内容。例如,如果需要用一些数据填充新列,则需要启动应用程序服务器,等待Hibernate创建新列并仅在此之后运行SQL脚本。如您所见,数据库迁移工具(例如Flyway,Liquibase等)几乎不可能在启用自动更新的情况下使用。

数据库更改不是集中的。借助Hibernate创建表和其他所有功能的可能性,很难监视应用程序每个版本中数据库的更改,因为其中大多数都是自动进行的。

鼓励对数据库进行垃圾处理。由于自动更新的“轻松”使用,您的团队有可能会忽略删除旧列和旧表,因为休眠自动更新无法做到这一点。

迫在眉睫的灾难。生产中发生灾难的迫在眉睫的风险(就像其他答案中提到的某些人一样)。即使应用程序已运行并已更新多年,我也不认为这是一个安全的选择。使用此选项我从未感到安全。

因此,我不建议在生产环境中使用自动更新。

如果您确实要在生产中使用自动更新,我建议:

分离网络。您的测试环境无法访问同源环境。这有助于防止应该在测试环境中进行的部署更改Homologation数据库。

管理脚本顺序。您需要组织脚本以在部署之前运行(结构表更改,删除表/列),并在部署之后运行脚本(新列/表的填充信息)。

而且,与其他帖子不同,我认为自动更新不会使它与“收入丰厚”的DBA相关(如其他帖子所述)。与编写SQL语句来创建/更改/删除表和列相比,DBA有更重要的事情要做。这些简单的日常任务可以由开发人员完成和自动化,并且只传递给DBA团队进行审查,而无需Hibernate和DBA“非常高薪”来编写。

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有