Java 休眠:hbm2ddl.auto=生产中的更新?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/221379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate: hbm2ddl.auto=update in production?
提问by cretzel
Is it okay to run Hibernate applications configured with hbm2ddl.auto=update
to update the database schema in a production environment?
hbm2ddl.auto=update
在生产环境中运行配置为更新数据库模式的Hibernate 应用程序是否可以?
采纳答案by Vladimir Dyuzhev
No, it's unsafe.
不,这是不安全的。
Despite the best efforts of the Hibernate team, you simply cannot rely on automatic updates in production. Write your own patches, review them with DBA, test them, then apply them manually.
尽管 Hibernate 团队做出了最大的努力,但您不能完全依赖生产中的自动更新。编写您自己的补丁,与 DBA 一起,测试它们,然后手动应用它们。
Theoretically, if hbm2ddl updateworked in development, it should work in production too. But in reality, it's not always the case.
理论上,如果hbm2ddl update在开发中起作用,它也应该在生产中起作用。但实际上,情况并非总是如此。
Even if it worked OK, it may be sub-optimal. DBAs are paid that much for a reason.
即使它工作正常,它也可能是次优的。DBA 的报酬如此之高是有原因的。
回答by Jaap Coomans
I wouldn't risk it because you might end up losing data that should have been preserved. hbm2ddl.auto=update is purely an easy way to keep your dev database up to date.
我不会冒险,因为您最终可能会丢失本应保留的数据。hbm2ddl.auto=update 纯粹是一种让您的开发数据库保持最新的简单方法。
回答by Brian Deterling
We do it in production albeit with an application that's not mission critical and with no highly paid DBAs on staff. It's just one less manual process that's subject to human error - the application can detect the difference and do the right thing, plus you've presumably tested it in various development and test environments.
我们在生产中这样做,尽管使用的应用程序不是关键任务,也没有高薪的 DBA。这只是少了一个容易出现人为错误的手动过程——应用程序可以检测差异并做正确的事情,而且您可能已经在各种开发和测试环境中对其进行了测试。
One caveat - in a clustered environment you may want to avoid it because multiple apps can come up at the same time and try to modify the schema which could be bad. Or put in some mechanism where only one instance is allowed to update the schema.
一个警告 - 在集群环境中,您可能希望避免它,因为多个应用程序可能同时出现并尝试修改可能不好的架构。或者采用某种机制,只允许一个实例更新架构。
回答by extraneon
I agree with Vladimir. The administrators in my company would definitely not appreciate it if I even suggested such a course.
我同意弗拉基米尔的看法。如果我提出这样的课程,我公司的管理员肯定不会欣赏。
Further, creating an SQL script in stead of blindly trusting Hibernate gives you the opportunity to remove fields which are no longer in use. Hibernate does not do that.
此外,创建 SQL 脚本而不是盲目地信任 Hibernate 使您有机会删除不再使用的字段。Hibernate 不会这样做。
And I find comparing the production schema with the new schema gives you even better insight to wat you changed in the data model. You know, of course, because you made it, but now you see all the changes in one go. Even the ones which make you go like "What the heck?!".
我发现将生产模式与新模式进行比较可以让您更好地了解数据模型中的变化。你当然知道,因为你做到了,但现在你可以一口气看到所有的变化。即使是那些让你像“这到底是什么?!”一样的东西。
There are tools which can make a schema delta for you, so it isn't even hard work. And then you know exactly what's going to happen.
有一些工具可以为您制作模式增量,因此它甚至不是艰苦的工作。然后你就知道会发生什么了。
回答by cliff.meyers
I would vote no. Hibernate doesn't seem to understand when datatypes for columns have changed. Examples (using MySQL):
我会投反对票。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
There are probably other examples as well, such as pushing the length of a String column up over 255 and seeing it convert to text, mediumtext, etc etc.
可能还有其他示例,例如将 String 列的长度向上推超过 255 并看到它转换为文本、中文本等。
Granted, I don't think there is really a way to "convert datatypes" with without creating a new column, copying the data and blowing away the old column. But the minute your database has columns which don't reflect the current Hibernate mapping you are living very dangerously...
诚然,我认为没有真正的方法可以在不创建新列、复制数据并清除旧列的情况下“转换数据类型”。但是,当您的数据库中的列不反映当前的 Hibernate 映射时,您的生活就非常危险......
Flyway is a good option to deal with this problem:
Flyway 是处理这个问题的好选择:
回答by cliff.meyers
Typically enterprise applications in large organizations run with reduced privileges.
Database username may not have
DDL
privilege for adding columns whichhbm2ddl.auto=update
requires.
通常,大型组织中的企业应用程序以降低的权限运行。
数据库用户名可能没有
DDL
添加hbm2ddl.auto=update
需要的列的权限。
回答by Pietro Polsinelli
Applications' schema may evolve in time; if you have several installations, which may be at different versions, you should have some way to ensure that your application, some kind of tool or script is capable of migrating schema and data from one version stepwise to any following one.
应用程序的模式可能会随着时间的推移而演变;如果您有多个安装,可能是不同的版本,您应该有一些方法来确保您的应用程序、某种工具或脚本能够将模式和数据从一个版本逐步迁移到任何后续版本。
Having all your persistence in Hibernate mappings (or annotations) is a very good way for keeping schema evolution under control.
在 Hibernate 映射(或注释)中保持所有持久性是控制模式演变的一种非常好的方法。
You should consider that schema evolution has several aspects to be considered:
您应该考虑模式演变有几个方面需要考虑:
evolution of the database schema in adding more columns and tables
dropping of old columns, tables and relations
filling new columns with defaults
数据库模式在添加更多列和表方面的演变
删除旧的列、表和关系
用默认值填充新列
Hibernate tools are important in particular in case (like in my experience) you have different versions of the same application on many different kinds of databases.
Hibernate 工具非常重要,特别是在(如我的经验)您在许多不同类型的数据库上拥有同一应用程序的不同版本的情况下。
Point 3 is very sensitive in case you are using Hibernate, as in case you introduce a new boolean valued property or numeric one, if Hibernate will find any null value in such columns, if will raise an exception.
第 3 点在您使用 Hibernate 的情况下非常敏感,因为如果您引入新的布尔值属性或数字属性,如果 Hibernate 会在此类列中找到任何空值,则会引发异常。
So what I would do is: do indeed use the Hibernate tools capacity of schema update, but you must add alongside of it some data and schema maintenance callback, like for filling defaults, dropping no longer used columns, and similar. In this way you get the advantages (database independent schema update scripts and avoiding duplicated coding of the updates, in peristence and in scripts) but you also cover all the aspects of the operation.
所以我要做的是:确实使用 Hibernate 工具的模式更新能力,但是你必须在它旁边添加一些数据和模式维护回调,比如填充默认值、删除不再使用的列等。通过这种方式,您可以获得优势(独立于数据库的模式更新脚本并避免更新的重复编码、持久性和脚本),但您还涵盖了操作的所有方面。
So for example if a version update consists simply in adding a varchar valued property (hence column), which may default to null, with auto update you'll be done. Where more complexity is necessary, more work will be necessary.
因此,例如,如果版本更新仅包括添加一个 varchar 值属性(因此列),该属性可能默认为 null,那么您将完成自动更新。在需要更复杂的地方,需要做更多的工作。
This is assuming that the application when updated is capable of updating its schema (it can be done), which also means that it must have the user rights to do so on the schema. If the policy of the customer prevents this (likely Lizard Brain case), you will have to provide the database - specific scripts.
这是假设应用程序在更新时能够更新其架构(可以完成),这也意味着它必须具有对架构执行此操作的用户权限。如果客户的政策阻止这种情况(可能是 Lizard Brain 案例),您将必须提供数据库特定的脚本。
回答by Roman
Hibernate creators discourage doing so in a production environment in their book "Java Persistence with Hibernate":
Hibernate 创建者在他们的书“Java Persistence with Hibernate”中不鼓励在生产环境中这样做:
WARNING: We've seen Hibernate users trying to use SchemaUpdate to update the schema of a production database automatically. This can quickly end in disaster and won't be allowed by your DBA.
警告:我们已经看到 Hibernate 用户尝试使用 SchemaUpdate 来自动更新生产数据库的架构。这可能很快以灾难告终,并且您的 DBA 不允许这样做。
回答by Robert
No, don't ever do it. Hibernate does not handle data migration. Yes, it will make your schema look correctly but it does not ensure that valuable production data is not lost in the process.
不,永远不要这样做。Hibernate 不处理数据迁移。是的,它会使您的架构看起来正确,但并不能确保在此过程中不会丢失有价值的生产数据。
回答by chris
We do it in a project running in production for months now and never had a problem so far. Keep in mind the 2 ingredients needed for this recipe:
我们在一个在生产中运行数月的项目中做到了这一点,到目前为止从未出现过问题。请记住此食谱所需的 2 种成分:
Design your object model with a backwards-compatibility approach, that is deprecateobjects and attributes rather than removing/altering them. This means that if you need to change the name of an object or attribute, leave the old one as is, add the new one and write some kind of migration script. If you need to change an association between objects, if you already are in production, this means that your design was wrong in the first place, so try to think of a new way of expressing the new relationship, without affecting old data.
Always backupthe database prior to deployment.
使用向后兼容的方法设计对象模型,即弃用对象和属性而不是删除/更改它们。这意味着如果您需要更改对象或属性的名称,请保留旧名称,添加新名称并编写某种迁移脚本。如果您需要更改对象之间的关联,如果您已经在生产中,这意味着您的设计首先是错误的,因此尝试想一种表达新关系的新方法,而不影响旧数据。
始终在部署之前备份数据库。
My sense is - after reading this post - that 90% of the people taking part in this discussion are horrified just with the thought of using automations like this in a production environment. Some throw the ballat the DBA. Take a moment though to consider that not all production environments will provide a DBA and not many dev teams are able to afford one (at least for medium size projects). So, if we're talking about teams where everyone has to do everything, the ball is on them.
我的感觉是 - 阅读这篇文章后 - 参与本次讨论的 90% 的人对在生产环境中使用这样的自动化的想法感到震惊。有些人把球扔给DBA。花点时间考虑一下,并非所有生产环境都提供 DBA,而且没有多少开发团队能够负担得起(至少对于中型项目而言)。所以,如果我们谈论的是每个人都必须做任何事情的球队,球就在他们身上。
In this case, why not just try to have the best of both worlds? Tools like this are here to give a helping hand, which - with a careful design and plan - can help in many situations. And believe me, administrators may initially be hard to convince but if they know that the ball is not on their hands, they will love it.
在这种情况下,为什么不尝试两全其美呢?像这样的工具可以提供帮助,通过精心设计和计划,它可以在许多情况下提供帮助。相信我,管理员最初可能很难说服,但如果他们知道球不在他们手上,他们会喜欢的。
Personally, I'd never go back to writing scripts by hand for extending any type of schema, but that's just my opinion. And after starting to adopt NoSQL schema-less databases recently, I can see that more than soon, all these schema-based operations will belong to the past, so you'd better start changing your perspective and look ahead.
就我个人而言,我永远不会回到手动编写脚本来扩展任何类型的模式,但这只是我的意见。而在最近开始采用 NoSQL 无模式数据库后,我可以看到,所有这些基于模式的操作很快就会成为过去,所以你最好开始改变你的观点并展望未来。