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


当前回答

在我的情况下(Hibernate 3.5.2, Postgresql, Ubuntu),设置Hibernate .hbm2ddl。Auto =update仅创建新表,并在已有的表中创建新列。 它既不删除表,也不删除列,也不更改列。它可以被称为一个安全的选择,但有点像hibernate.hbm2ddl。Auto =create_tables add_columns更清楚。

其他回答

应用程序的模式可能会随着时间而变化;如果您有多个安装,可能是不同的版本,您应该有某种方法来确保您的应用程序、某种工具或脚本能够逐步将模式和数据从一个版本迁移到下一个版本。

将所有持久性放在Hibernate映射(或注释)中是控制模式演变的一种非常好的方法。

您应该考虑模式演化有几个方面需要考虑:

数据库模式的演变 添加更多的列和表 删除旧的列,表和 关系 用默认值填充新列

Hibernate工具非常重要,特别是当你在许多不同类型的数据库上有相同应用程序的不同版本时(就像我的经验一样)。

第3点在使用Hibernate时非常敏感,例如在引入一个新的布尔值属性或数值属性时,如果Hibernate在这些列中发现任何空值,则会引发异常。

所以我要做的是:确实使用Hibernate工具的模式更新功能,但必须在它旁边添加一些数据和模式维护回调,比如填充默认值,删除不再使用的列,等等。通过这种方式,您获得了优势(独立于数据库的模式更新脚本和避免在持久性和脚本中对更新进行重复编码),但也涵盖了操作的所有方面。

因此,例如,如果版本更新只是添加一个varchar值属性(即列),它可能默认为null,那么使用自动更新就可以完成。在需要更复杂的地方,就需要做更多的工作。

这是假设更新时的应用程序能够更新其模式(这是可以做到的),这也意味着它必须拥有对模式进行更新的用户权限。如果客户的策略阻止了这一点(可能是Lizard Brain的情况),您将不得不提供特定于数据库的脚本。

通常,大型组织中的企业应用程序以较少的权限运行。 数据库用户名可能没有DDL权限,不能添加hbm2ddl的列。汽车=更新要求。

不,永远不要这么做。Hibernate不处理数据迁移。是的,它将使您的模式看起来正确,但它不能确保有价值的生产数据不会在过程中丢失。

我会投反对票。当列的数据类型发生变化时,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

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

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