使用JPA初始插入播放框架

时间:2014-09-19 15:29:08

标签: java hibernate jpa playframework

我使用Play 2.3和Hibernate。 在第一次启动应用程序时,我希望将一些数据作为默认值插入到数据库中。

在我的情况下,我有一个实体课" Studycourse"。所有表都是在首次运行时通过JPA创建的。

我使用DB evolution(1.sql)来插入默认数据,例如:

INSERT INTO studycourse (id, title) VALUES (1, 'Computer Science');

这在使用普通"激活器运行"命令。但如果我做了#34;激活测试"并使用inMemoryDatabase()开始一个简单的集成测试,我得到以下错误:

[error] play - Table "STUDYCOURSE" not found; SQL statement: INSERT INTO studycourse (id, title) VALUES (1, 'Computer Science')

我想,初始JPA设置不是在内存数据库中完成的。

问题:有关于如何做到这一点的最佳做法吗?

集成测试如下:

public class IntegrationTest {
    @Test
    public void test() {
        running(testServer(3333, fakeApplication(inMemoryDatabase())), HTMLUNIT, new Callback<TestBrowser>() {
            public void invoke(TestBrowser browser) {
                browser.goTo("http://localhost:3333");
                assertThat(browser.pageSource()).contains("Your new application is ready.");
            }
        });
    }
}

提前致谢。

1 个答案:

答案 0 :(得分:0)

你原来的问题实际上是在询问&#34;我如何在测试环境中执行我的JPA初始化步骤,以便在运行涉及我的数据库的集成测试时填充我的内存数据库?&#34;。

我的回答不会直接解决这个问题,但会总结我们如何解决您尝试解决的相同潜在问题。

我对你的目标的解释是你想:

  • 建立数据库架构迁移的良好实践
  • 建立数据库集成测试的通用实践

数据库架构迁移

正如我在上面的评论中提到的,我们使用http://flywaydb.org进行数据库架构迁移,它一直是一个出色的工具。 Flyway有一个SBT插件,因此您可以从flywayClean直接运行flywayMigrateactivator来立即删除并重新初始化您的数据库。

Flyway支持复杂的文件名版本,因此您可以执行v1.1.0.sqlv1.1.1.sqlv1.2.0.sql等SQL脚本。如果您尝试执行的迁移脚本不是对数据库现有状态的纯粹改进,那么Flyway也会抱怨。这意味着我们正在使用flyway将数据库模式迁移推向生产,如果我们做了一些愚蠢的事情,我们相信这会失败。当然,为了安全起见,我们总是在迁移之前进行数据库备份。

最后,如果你想使用服务方法而不仅仅是原始SQL,Flyway甚至会让你执行java程序来填充数据库。

无论如何,你在这里的选择基本上是Play evolutions,Flyway或Liquibase。

内存数据库与开发数据库

在这个问题上,我看到了两个主要职位:

  1. 永远不要在内存数据库上进行测试,因为那样你的测试就不会出现 揭示内存数据库和内存数据库之间的微妙差异 您的生产数据库,或

  2. 使用内存数据库进行本地测试,但至少要有你的 构建服务器使用开发数据库。

  3. 例如,您可以在http://blog.jooq.org/2014/06/26/stop-unit-testing-database-code/结尾处看到评论。

    选项#1总体上提供了更高的速度,但延迟了编写错误代码和进行失败的集成测试之间的反馈时间。

    选项#2总体上会略微降低速度,但会为您提供有关真实数据库的即时反馈。

    与工程中的大多数事情一样,没有最好的&#34;解决方案,只是一组对您的团队最有意义的权衡。

    选择ORM图层

    我们最初从Hibernate开始,但最终切换到http://jooq.org。有关jOOQ积极概述,请参阅http://www.vertabelo.com/blog/technical-articles/jooq-a-really-nice-alternative-to-hibernate;有关这两者的详细讨论,请参见http://blog.jooq.org/2012/04/21/jooq-and-hibernate-a-discussion/

    Hibernate似乎对我们很有吸引力,因为它非常成熟且非常流行,但是当我们开始遇到经典的SQL与面向对象的阻抗不匹配(如如何处理继承)时,Hibernate需要学习曲线和一些设置开销。

    我们推断,如果我们要承担这种开销,为什么不直接使用SQL来进行映射呢?因此,我们切换到JOOQ并且能够编写一些非常干净,优雅且可测试的代码。如果你在休眠路径上走得太远,我建议你去看看jOOQ。

    如果您已经深入了解Hibernate并且它对您有用,那么转换可能没什么价值。

    数据库集成测试的最佳实践

    我想知道这个确切的问题并在https://groups.google.com/forum/#!topic/jooq-user/GkBW5ZGdgwQ发布了这个问题。 jOOQ的作者Lukas回应了一些一般性的评论。

    此时,我们对大多数DAO和服务类进行了集成测试。我们的测试是在flywayCleanflywayMigrate运行后运行的。然后,编写每个测试以进行清理。最大的问题是性能,到目前为止这不是一个问题,但可能会在以后出现问题。

    我也发布了这个并收到了一个有用的答案。请参阅https://groups.google.com/d/msg/play-framework/BgOCIgz_9q0/jBy8zxejPEkJ

    免责声明:我们即将启动我们的应用程序,但尚未在生产环境中运行,因此其他人可能还有其他最佳实践要添加。