是否可以运行配置了hbm2ddl的Hibernate应用程序。自动=update在生产环境中更新数据库模式?


当前回答

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

警告:我们已经看到Hibernate用户试图使用SchemaUpdate自动更新生产数据库的模式。这很快就会导致灾难,而且DBA不允许这样做。

其他回答

我会投反对票。当列的数据类型发生变化时,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以上,然后看到它转换为文本、mediumtext等等。

当然,我不认为真的有一种方法可以在不创建新列、复制数据和删除旧列的情况下“转换数据类型”。但是一旦你的数据库中有不能反映当前Hibernate映射的列,你就非常危险了……

Flyway是解决这个问题的一个很好的选择:

http://flywaydb.org

这不安全,也不推荐,但这是可能的。

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

在这个解决方案中发现的主要问题和风险是:

Deploy in the wrong database. If you commit the mistake to run the application server with a old version of the application (EAR/WAR/etc) in the wrong database... You will have a lot of new columns, tables, foreign keys and errors. The same problem can occur with a simple mistake in the datasource file, (copy/paste file and forgot to change the database). In resume, the situation can be a disaster in your database. Application server takes too long to start. This occur because the Hibernate try to find all created tables/columns/etc every time you start the application. He needs to know what (table, column, etc) needs to be created. This problem will only gets worse as the database tables grows up. Database tools it's almost impossible to use. To create database DDL or DML scripts to run with a new version, you need to think about what will be created by the auto-update after you start the application server. Per example, If you need to fill a new column with some data, you need to start the application server, wait to Hibernate crete the new column and run the SQL script only after that. As can you see, database migration tools (like Flyway, Liquibase, etc) it's almost impossible to use with auto-update enabled. Database changes is not centralized. With the possibility of the Hibernate create tables and everything else, it's hard to watch the changes on database in each version of the application, because most of them are made automatically. Encourages garbage on database. Because of the "easy" use of auto-update, there is a chance your team neglecting to drop old columns and old tables, because the hibernate auto-update can't do that. Imminent disaster. The imminent risk of some disaster to occur in production (like some people mentioned in other answers). Even with an application running and being updated for years, I don't think it's a safe choice. I never felt safe with this option being used.

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

如果你真的想在生产环境中使用自动更新,我建议:

网络分开。您的测试环境无法访问同源环境。这有助于防止原本应该在测试环境中的部署更改同源数据库。 管理脚本顺序。您需要在部署之前(结构表更改、删除表/列)和部署之后(填充新列/表的信息)组织运行的脚本。

而且,与其他文章不同的是,我不认为自动更新启用了它与“高薪”dba有关(如其他文章所述)。dba有比编写SQL语句来创建/更改/删除表和列更重要的事情要做。这些简单的日常任务可以由开发人员完成和自动化,只需要DBA团队进行检查,而不需要Hibernate和DBA“高薪”编写它们。

我们在生产环境中进行,尽管应用程序不是关键任务,也没有高薪的dba。这只是减少了一个受人为错误影响的手动过程——应用程序可以检测到差异并做正确的事情,而且您可能已经在各种开发和测试环境中对其进行了测试。

一个警告——在集群环境中,你可能想要避免它,因为多个应用程序可能会同时出现,并试图修改模式,这可能是不好的。或者放入某种只允许一个实例更新模式的机制。

我同意弗拉基米尔的观点。如果我提出这样的课程,我公司的管理人员肯定不会感激。

此外,创建SQL脚本而不是盲目地信任Hibernate,使您有机会删除不再使用的字段。Hibernate不会这样做。

我发现,比较生产模式和新模式可以让您更好地了解数据模型中所更改的内容。当然,你知道,因为你成功了,但现在你看到所有的变化一气呵成。即使是那些让你想“搞什么鬼?!”

有一些工具可以为您创建模式增量,因此这甚至不是一项艰巨的工作。然后你就知道会发生什么了。

我不会冒这个险,因为你可能会丢失本该保存的数据。hbm2ddl。Auto =update纯粹是一种保持开发数据库最新的简单方法。