我将Play项目从版本2.3.4迁移到2.4.2。这些项目使用JPA(Hibernate)和Evolutions。我有一个最初的Evolutions SQL脚本,它用一些示例数据填充数据库。此脚本现在不再起作用,因为Evolutions脚本现在在Hibernate生成表之前执行,这显然会导致错误。这是一个理想的行为吗?有没有办法改变执行顺序?
答案 0 :(得分:0)
演变是关于通过纯SQL脚本创建和更新数据库。因此,如果你使用一些生成数据表的框架,比如hibernate,那么你需要关闭进化(或关闭自动生成并仅使用进化)
在启动时填写数据库
我在Cassandra上遇到了类似的问题,我做了什么 - 只需创建一个读取CQL文件并执行它的代码,然后在创建实际数据表后运行此代码。
我认为Hibernate已经具备此功能 - 您需要将自定义SQL代码放入类路径根目录中的/import.sql
文件中:
如果类路径的根目录中存在名为import.sql的文件('/import.sql'),Hibernate将在创建数据库模式后执行从该文件读取的SQL语句。
答案 1 :(得分:0)
从2.3升级到2.4后,我遇到了同样的问题,因为我使用Hibernate在内存db中创建了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);
}
}
自游戏2.4版以来,发生了一些变化,并且在游戏演进后被称为休眠模式。为了解决这个问题,我在集成主义者的配置中转而使用了自动进化功能
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);
});
}
我不同意我们不能同时使用Evolution和Hibernate。我发现将两者都用于集成测试是一个完美的解决方案。如果只想使用演进,则问题在于演进与数据库相关,因此MySQL演进不适用于H2 db。第二个原因是我针对不同的测试用例使用了不同的演变,并且需要针对每个演变对所有脚本和方案进行复制粘贴。
我相信使用Hibernate创建用于集成测试的方案完全可以,并且2.4更改是一个重大更改,应该记录在案。
这是我的存储库,带有play 2.6的工作示例,但它也应该与play> = 2.4 githubrepository
一起工作