cre*_*zel 324 java hibernate hbm2ddl
是否可以运行配置的Hibernate应用程序hbm2ddl.auto=update来更新生产环境中的数据库模式?
Vla*_*hev 374
不,这不安全.
尽管Hibernate团队做出了最大努力,但您根本无法依靠生产中的自动更新.编写自己的补丁,使用DBA进行检查,测试它们,然后手动应用它们.
从理论上讲,如果hbm2ddl update在开发中有效,它也应该在生产中工作.但实际上,并非总是如此.
即使它工作正常,也可能是次优的.DBA因为某种原因得到了很多报酬.
Bri*_*ing 70
我们在生产中实现这一点,尽管应用程序不是关键任务,并且员工没有高薪DBA.它只是一个人为错误的手动过程 - 应用程序可以检测到差异并做正确的事情,而且您可能已经在各种开发和测试环境中对其进行了测试.
一个警告 - 在集群环境中,您可能希望避免它,因为多个应用程序可以同时出现并尝试修改可能不好的架构.或者放入一些只允许一个实例更新架构的机制.
Rom*_*man 52
Hibernate创建者不鼓励在他们的书"Java Persistence with Hibernate"中的生产环境中这样做:
警告:我们已经看到Hibernate用户尝试使用SchemaUpdate自动更新生产数据库的模式.这很快就会以灾难告终,您的DBA将不允许这样做.
jps*_*ain 28
查看LiquiBase XML以保留更新的更新日志.我从来没有使用它,直到今年,但我发现它很容易学习,并使数据库修订控制/迁移/变更管理非常万无一失.我在Groovy/Grails项目上工作,Grails在其下面使用Hibernate来创建所有ORM(称为"GORM").我们使用Liquibase来管理所有SQL架构更改,当我们的应用程序随新功能发展时,我们会经常这样做.
基本上,您保留一个变更集的XML文件,您可以随着应用程序的发展继续添加这些变量集.这个文件与你的项目的其余部分一起保存在git(或者你正在使用的任何东西)中.部署应用程序时,Liquibase会检查您要连接的数据库中的更改日志表,以便知道已经应用了什么,然后智能地应用文件中尚未应用的任何更改集.它在实践中非常有用,如果您将它用于所有架构更改,那么您可以100%确信您签出和部署的代码始终能够连接到完全兼容的数据库架构.
令人敬畏的是,我可以在笔记本电脑上使用一个完全空白的slate mysql数据库,启动应用程序,然后立即为我设置架构.它还可以通过首先将这些更改应用于local-dev或staging db来轻松测试模式更改.
开始使用它的最简单方法可能是获取现有数据库,然后使用Liquibase生成初始baseline.xml文件.然后在将来,您可以添加到它并让liquibase接管管理架构更改.
cli*_*ers 26
我会投票否决.当列的数据类型发生更改时,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
Run Code Online (Sandbox Code Playgroud)
可能还有其他示例,例如将String列的长度超过255并将其转换为text,mediumtext等.
当然,我认为没有真正的方法可以在不创建新列的情况下"转换数据类型",复制数据并吹掉旧列.但是,当您的数据库具有不反映当前Hibernate映射的列时,您生活得非常危险......
Flyway是处理这个问题的好方法:
joh*_*ein 25
Hibernate必须放弃关于不使用自动更新的免责声明,以便当不知道他们正在做什么的人在不应该使用它的情况下使用它时自己覆盖.
在不应该使用的情况下,可以大大超过那些可以使用的情况.
我已经在很多不同的项目上使用它多年,从来没有遇到过一个问题.这不是一个蹩脚的答案,而不是牛仔编码.这是一个历史事实.
一个说"从不在生产中做"的人正在考虑一组特定的生产部署,即他熟悉的那些(他的公司,他的行业等).
"生产部署"的范围广泛而多样.
经验丰富的Hibernate开发人员确切知道DDL将从给定的映射配置中产生什么.只要你测试并验证你期望在DDL中的内容(在dev,qa,staging等中),你就可以了.
当您添加许多功能时,自动架构更新可以节省大量时间.
自动更新无法处理的内容列表是无穷无尽的,但一些示例是数据迁移,添加不可为空的列,列名称更改等.
您还需要在群集环境中小心.
但话说回来,如果你知道所有这些东西,你就不会问这个问题了.嗯...好的,如果你问这个问题,你应该等到你有很多Hibernate和自动架构更新的经验,然后才考虑在prod中使用它.
Vla*_*cea 17
正如我在本文中所解释的那样,hbm2ddl.auto在生产中使用它并不是一个好主意.
管理数据库模式的唯一方法是使用增量迁移脚本,因为:
即使是" Hibernate用户指南"也建议您避免在hbm2ddl生产环境中使用该工具.
我不会冒险,因为你最终可能会丢失应该保留的数据.hbm2ddl.auto = update纯粹是一种让您的dev数据库保持最新的简单方法.
小智 7
我们在一个项目中运行了几个月,到目前为止从未出现过问题.请记住此配方所需的2种成分:
使用向后兼容性方法设计对象模型,即弃用对象和属性,而不是删除/更改它们.这意味着如果您需要更改对象或属性的名称,请保留原有的名称,添加新的名称并编写某种迁移脚本.如果您需要更改对象之间的关联,如果您已经在生产中,这意味着您的设计首先是错误的,因此请尝试考虑一种表达新关系的新方式,而不会影响旧数据.
始终在部署之前备份数据库.
我的感觉是 - 在阅读这篇文章后 - 参与讨论的人中有90%只是想到在生产环境中使用这样的自动化.有些人把球扔到了DBA.花一点时间考虑并非所有生产环境都会提供DBA,并且没有多少开发团队能够负担得起(至少对于中等规模的项目).所以,如果我们谈论的是每个人都必须做所有事情的球队,球就在他们身上.
在这种情况下,为什么不尝试两全其美?像这样的工具可以提供帮助,通过精心的设计和计划,可以在许多情况下提供帮助.相信我,管理员最初可能很难说服,但如果他们知道球不在他们手上,他们就会喜欢它.
就个人而言,我永远不会再手工编写脚本来扩展任何类型的架构,但这只是我的意见.在最近开始采用NoSQL无架构数据库之后,我可以看到,所有这些基于模式的操作都将属于过去,因此您最好开始改变您的观点并展望未来.
小智 6
在我的例子中(Hibernate 3.5.2,Postgresql,Ubuntu),设置hibernate.hbm2ddl.auto=update只创建新表并在现有表中创建新列.
它既没有删除表,也没有删除列,也没有改变列.它可以被称为安全选项,但类似的东西hibernate.hbm2ddl.auto=create_tables add_columns会更清楚.
这不安全,不建议使用,但是有可能。
我在生产中使用自动更新选项的应用程序中有经验。
好了,此解决方案中发现的主要问题和风险是:
因此,我不建议在生产环境中使用自动更新。
如果您确实要在生产中使用自动更新,我建议:
而且,与其他帖子不同,我认为自动更新不会使它与“收入丰厚”的DBA相关(如其他帖子所述)。与编写SQL语句来创建/更改/删除表和列相比,DBA有更重要的事情要做。这些简单的日常任务可以由开发人员完成和自动化,并且只传递给DBA团队进行审查,而无需Hibernate和DBA“非常高薪”来编写。