【问题标题】:Play Evolutions and JPA in Play Framework 2.4Play Framework 2.4 中的 Play Evolutions 和 JPA
【发布时间】:2015-10-08 17:21:59
【问题描述】:

我将一个 Play 项目从 2.3.4 版迁移到 2.4.2 版。这些项目使用 JPA (Hibernate) 和 Evolutions。我有一个初始的 Evolutions SQL 脚本,它用一些示例数据填充数据库。这个脚本现在不再工作了,因为 Evolutions 脚本现在在 Hibernate 生成表之前执行,这显然会导致错误。这是理想的行为吗?有什么办法可以改变执行顺序吗?

【问题讨论】:

    标签: hibernate jpa playframework playframework-2.4 playframework-evolutions


    【解决方案1】:

    演变是关于通过普通 SQL 脚本创建和更新数据库。所以如果你使用一些自己生成数据表的框架,比如hibernate,那么你需要关闭进化(或者关闭自动生成并且只使用进化)

    启动时填充数据库

    我在 Cassandra 上遇到了类似的问题,我做了什么 - 只需创建一个读取 CQL 文件并执行它的代码,然后在创建实际数据表后运行此代码。

    正如我所见,Hibernate 已经拥有此功能 - 您需要将自定义 SQL 代码放入类路径根目录下的 /import.sql 文件中:

    如果类路径('/import.sql')的根目录下存在名为 import.sql 的文件,则 Hibernate 将在创建数据库模式后执行从该文件中读取的 SQL 语句。

    【讨论】:

    • 感谢您的详细回答,但我不同意。 Play 文档指出:“当您使用关系数据库时,您需要一种方法来跟踪和组织您的数据库模式演变”。这并没有说明如何访问该数据库。在我看来,Evolutions 是对 Hibernate 的完美补充,因为 Hibernate 只有有限的迁移可能性。关键是,它在 Play 中运行了多年,所以我认为这是一个错误。
    • 您写了“Hibernate 生成表”,这意味着 Hibernate 组织您的数据库。您只需要使用一种数据库更新机制——进化或休眠表生成。如果您想使用进化,请关闭 Hibernate 表生成:stackoverflow.com/questions/221379/…
    • 警告:我们已经看到 Hibernate 用户尝试使用 SchemaUpdate 自动更新生产数据库的模式。这可能很快以灾难告终,并且您的 DBA 不允许这样做。
    【解决方案2】:

    在从 2.3 升级到 2.4 后我遇到了同样的问题我的测试没有工作,因为我使用 Hibernate 在内存数据库中的 H2 中创建所有表,并为使用测试用例的数据准备数据库进行进化。

    我的测试基地是这样的

    public abstract class TestServerBase extends WithServer {
        public static String H2_URL =  "jdbc:h2:mem:glamazon;MODE=MySQL;REFERENTIAL_INTEGRITY=False";
    
        public abstract String getDb();
    
        @Override
        protected FakeApplication provideFakeApplication() {
            final String db = getDb();
            final Map config = new HashMap();
            config.put(String.format("db.%s.driver",db), "org.h2.Driver");
            config.put(String.format("db.%s.url",db), H2_URL);
            config.put(String.format("db.%s.user",db), "");
            config.put(String.format("db.%s.password",db), "");
            config.put(String.format("db.%s.jndiName",db), "DefaultDS");
            return Helpers.fakeApplication(config);
        }
    }
    

    自 play 2.4 以来发生了一些变化,并且在 play 演变后调用了休眠。为了解决这个问题,我在我的集​​成器配置中关闭了自动进化

    play.evolutions.enabled=false
    

    我想出了我的 TestServerBase 的新方法

    @Before
    public void runEvolutions(){
        final Database db = Databases.createFrom(getDb(),"org.h2.Driver", H2_URL);
        JPA.withTransaction(() ->{
            Evolutions.applyEvolutions(db);
        });
    }
    
    @After
    public void deleteEvolutions(){
        final Database db = Databases.createFrom(getDb(),"org.h2.Driver", H2_URL);
        JPA.withTransaction(() ->{
            Evolutions.cleanupEvolutions(db);
        });
    
    }
    

    我不同意我们不能同时使用 Evolutions 和 Hibernate。我发现将两者都用于集成测试是一个完美的解决方案。如果您只想使用进化,问题是进化与数据库相关,因此 MySQL 进化不适用于 H2 db。第二个原因是我对不同的测试用例使用了不同的演进,我需要为每个演进复制粘贴所有带有方案的脚本。

    我相信使用 Hibernate 来创建集成测试方案是完全可以的,而且 2.4 的更改是一个重大更改,应该记录在案。

    这是我的存储库,其中包含 play 2.6 的工作示例,但它也应该适用于 play >= 2.4 githubrepository

    【讨论】:

      猜你喜欢
      • 2015-10-02
      • 2015-08-16
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多