7

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

4

2 回答 2

0

从 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 演变后调用了 hibernate。为了解决这个问题,我在我的集​​成器配置中关闭了自动进化

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

于 2018-10-29T23:10:54.503 回答
0

Evolutions 是关于通过纯 SQL 脚本创建和更新数据库的。因此,如果您使用一些自己生成数据表的框架,例如休眠,那么您需要关闭进化(或关闭自动生成并仅使用进化)

启动时填充数据库

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

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

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

于 2015-11-11T08:51:54.377 回答