当我使用JPA时,如何管理数据库演变?

时间:2022-03-08 07:15:26

I learned play by following the tutorial on their website for building a little blogging engine.

我通过在他们的网站上按照教程构建一个小博客引擎来学习游戏。

It uses JPA and in it's bootstrap calls Fixtures.Deletemodels(), (or something like that).

它使用JPA并在其引导程序中调用Fixtures.Deletemodels(),(或类似的东西)。

It basically nukes all the tables every time it runs and I lose all the data.

它每次运行时基本上都会核对所有表,我丢失了所有数据。

I've deployed a production system like (sans the nuke statement).

我已经部署了一个生产系统(没有nuke声明)。

Now I need to deploy a large update to the production system. Lots of classes have changed, been added, and been removed. In my testing locally, without nuking the tables on every run I ran into sync issues. When I would try to write or read from tables play would throw errors. I opened up mysql and sure enough the tables had only been partially modified and modified incorrectly in some cases. Even if I have the DDL mode set to "create" in my config JPA can't seem to "figure out" how to reconcile the changes and modify my schema accordingly.

现在我需要将大量更新部署到生产系统。许多类已更改,已添加并已删除。在我的本地测试中,我没有在每次运行时查看表,而是遇到了同步问题。当我试图写或从表中读取时,播放会抛出错误。我打开了mysql,确定表格在某些情况下只是部分修改和修改不正确。即使我在我的配置中将DDL模式设置为“create”,JPA也似乎无法“弄清楚”如何协调更改并相应地修改我的架构。

So I have to put back in the bootstrap statement that nukes all my tables.

所以我必须回到我所有桌子的核心引导声明中。

So I started looking into database evolutions within Play and read an article on the play framework website about database evolutions. The article talked about version scripts, but it said, "If you work with JPA, Hibernate can handle database evolutions for you automatically. Evolutions are useful if you don’t use JPA".

所以我开始研究Play中的数据库演变,并在play框架网站上阅读有关数据库演变的文章。文章讨论了版本脚本,但它说,“如果您使用JPA,Hibernate可以自动处理数据库演变。如果您不使用JPA,演变很有用”。

So if JPA is supposed to be taking care of this for me, how do I deploy large updates to a large Play app? So far JPA has not been able to make the schema changes correctly and the app will throw errors. I'm not interested in losing all my data so the fix on dev "Fixtures.deleteModels()" can't really be used in prod.

因此,如果JPA应该为我处理这个问题,我该如何在大型Play应用程序中部署大型更新?到目前为止,JPA无法正确更改架构,应用程序将抛出错误。我对丢失我的所有数据并不感兴趣,所以修复dev“Fixtures.deleteModels()”无法真正用于prod。

Thanks in advance, Josh

先谢谢你,乔希

4 个解决方案

#1


7  

No, JPA should not take care of it for you. It's not a magic tool. If you decide to rename the table "client" to "customer", the column "street" to "line1" and to switch the values of the customer type column from 1, 2, 3 to "bronze", "silver", "gold", there is no way for JPA to read in your mind and figure all the changes to do automagically.

不,JPA不应该为你照顾它。这不是一个神奇的工具。如果您决定将表“client”重命名为“customer”,将“street”列重命名为“line1”,并将客户类型列的值从1,2,3切换为“bronze”,“silver”,“黄金“,JPA没有办法在你的脑海里读到并想象所有变化都是自动完成的。

To migrate from one schema to another, you use the same tools as if you didn't use JPA: SQL scripts, or more adavanced schema and data migration tools, or even custom migration JDBC code.

要从一个模式迁移到另一个模式,可以使用相同的工具,就像不使用JPA:SQL脚本,或更高级的模式和数据迁移工具,甚至是自定义迁移JDBC代码一样。

#2


4  

Have a look at flyway. You may trigger database migrations from your code or maven.

看看飞路。您可以从代码或maven中触发数据库迁移。

#3


0  

There is a property called hbm2ddl.auto=update which will update your schema. I would STRONGLY suggest to not use this setting in production as it introduces a whole new level of problems if something goes wrong. It's perfectly fine for development though.

有一个名为hbm2ddl.auto = update的属性将更新您的架构。我强烈建议不要在生产中使用这个设置,因为如果出现问题,它会引入一个全新的问题。尽管如此,这对于开发来说完全没问题。

#4


0  

When a JPA container starts (say, EclipseLink or any other), it expects to find a database which matches @Entity classes you've defined in your code. If the database has been migrated already, everything will work smoothly; otherwise: probably it will fail.

当JPA容器启动时(例如,EclipseLink或任何其他容器),它期望找到一个与您在代码中定义的@Entity类匹配的数据库。如果数据库已经迁移,一切都会顺利进行;否则:可能会失败。

So, long story short, you need to perform database migrations (or evolutions, if you prefer) before the JPA container starts. Apparently, Play performs migrations for you, before Play kicks off the database manager you configured. So, in theory, regardless the ORM you are using, Play decides when it's time for the ORM to start its work. So, conceptually it should work.

因此,简而言之,您需要在JPA容器启动之前执行数据库迁移(或者,如果您愿意,进行演进)。显然,在Play启动您配置的数据库管理器之前,Play会为您执行迁移。因此,理论上,无论您使用的是ORM,Play都会决定ORM何时开始工作。所以,从概念上讲它应该有效。

For a good presentation about this subject, please have a look at the second video at: http://flywaydb.org/documentation/videos.html

有关此主题的精彩演示,请查看第二个视频:http://flywaydb.org/documentation/videos.html

#1


7  

No, JPA should not take care of it for you. It's not a magic tool. If you decide to rename the table "client" to "customer", the column "street" to "line1" and to switch the values of the customer type column from 1, 2, 3 to "bronze", "silver", "gold", there is no way for JPA to read in your mind and figure all the changes to do automagically.

不,JPA不应该为你照顾它。这不是一个神奇的工具。如果您决定将表“client”重命名为“customer”,将“street”列重命名为“line1”,并将客户类型列的值从1,2,3切换为“bronze”,“silver”,“黄金“,JPA没有办法在你的脑海里读到并想象所有变化都是自动完成的。

To migrate from one schema to another, you use the same tools as if you didn't use JPA: SQL scripts, or more adavanced schema and data migration tools, or even custom migration JDBC code.

要从一个模式迁移到另一个模式,可以使用相同的工具,就像不使用JPA:SQL脚本,或更高级的模式和数据迁移工具,甚至是自定义迁移JDBC代码一样。

#2


4  

Have a look at flyway. You may trigger database migrations from your code or maven.

看看飞路。您可以从代码或maven中触发数据库迁移。

#3


0  

There is a property called hbm2ddl.auto=update which will update your schema. I would STRONGLY suggest to not use this setting in production as it introduces a whole new level of problems if something goes wrong. It's perfectly fine for development though.

有一个名为hbm2ddl.auto = update的属性将更新您的架构。我强烈建议不要在生产中使用这个设置,因为如果出现问题,它会引入一个全新的问题。尽管如此,这对于开发来说完全没问题。

#4


0  

When a JPA container starts (say, EclipseLink or any other), it expects to find a database which matches @Entity classes you've defined in your code. If the database has been migrated already, everything will work smoothly; otherwise: probably it will fail.

当JPA容器启动时(例如,EclipseLink或任何其他容器),它期望找到一个与您在代码中定义的@Entity类匹配的数据库。如果数据库已经迁移,一切都会顺利进行;否则:可能会失败。

So, long story short, you need to perform database migrations (or evolutions, if you prefer) before the JPA container starts. Apparently, Play performs migrations for you, before Play kicks off the database manager you configured. So, in theory, regardless the ORM you are using, Play decides when it's time for the ORM to start its work. So, conceptually it should work.

因此,简而言之,您需要在JPA容器启动之前执行数据库迁移(或者,如果您愿意,进行演进)。显然,在Play启动您配置的数据库管理器之前,Play会为您执行迁移。因此,理论上,无论您使用的是ORM,Play都会决定ORM何时开始工作。所以,从概念上讲它应该有效。

For a good presentation about this subject, please have a look at the second video at: http://flywaydb.org/documentation/videos.html

有关此主题的精彩演示,请查看第二个视频:http://flywaydb.org/documentation/videos.html