在 Maven 中使用带有 Flyway 和 jOOQ 的嵌入式数据库进行持续集成

Posted

技术标签:

【中文标题】在 Maven 中使用带有 Flyway 和 jOOQ 的嵌入式数据库进行持续集成【英文标题】:Using embedded database with Flyway and jOOQ in Maven for continuous integration 【发布时间】:2015-04-08 18:40:07 【问题描述】:

所以我真的想用SQL that will break at compile time using flyway and jOOQ 做“正确”的事情。为此,我需要一个可以在continuous integration server 上工作且无法访问任何基于服务器的数据库的数据库解决方案。最终,我想将它部署到 Amazon,所以我需要一个解决方案,即 mostly compatible with postgreSQL。 HSQLDB's file protocol 似乎符合这个要求。

<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                  http://maven.apache.org/xsd/maven-4.0.0.xsd">

<properties>
    <schema></schema>
    <db.groupId>org.hsqldb</db.groupId>
    <db.artifactId>hsqldb</db.artifactId>
    <db.version>2.3.2</db.version>
    <flyway.url>jdbc:hsqldb:file:myDB/db</flyway.url>
    <flyway.driver>org.hsqldb.jdbcDriver</flyway.driver>
    <jooq.generator.database.name>org.jooq.util.hsqldb.HSQLDBDatabase</jooq.generator.database.name>
    <flyway.user></flyway.user>
    <flyway.password></flyway.password>

</properties>

<dependencies>
    <dependency>
        <groupId>$db.groupId</groupId>
        <artifactId>$db.artifactId</artifactId>
        <version>$db.version</version>
    </dependency>
    <dependency>
        <groupId>org.jooq</groupId>
        <artifactId>jooq</artifactId>
        <version>3.4.2</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-maven-plugin</artifactId>
            <version>3.1</version>

            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>migrate</goal>
                    </goals>
                </execution>
            </executions>

            <configuration>
                <locations>
                    <location>filesystem:src/main/resources/db/migration</location>
                </locations>
            </configuration>
        </plugin>
        <plugin>

            <!-- Specify the maven code generator plugin -->
            <groupId>org.jooq</groupId>
            <artifactId>jooq-codegen-maven</artifactId>
            <version>3.4.2</version>

            <!-- The plugin should hook into the generate goal -->
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>

            <!-- Work around Maven's classloader -->
            <dependencies>
                <dependency>
                    <groupId>$db.groupId</groupId>
                    <artifactId>$db.artifactId</artifactId>
                    <version>$db.version</version>
                </dependency>
            </dependencies>

            <configuration>

                <!-- JDBC connection parameters -->
                <jdbc>
                    <driver>$flyway.driver</driver>
                    <url>$flyway.url</url>
                    <user>$flyway.user</user>
                    <password>$flyway.password</password>
                </jdbc>

                <!-- Generator parameters -->
                <generator>
                    <name>org.jooq.util.DefaultGenerator</name>
                    <database>
                        <name>$jooq.generator.database.name</name>
                        <includes>.*</includes>
                        <excludes></excludes>
                        <inputSchema>$schema</inputSchema>
                    </database>
                    <target>
                        <packageName>package.goes.here</packageName>
                        <directory>target/generated-sources/jooq</directory>
                    </target>
                </generator>
            </configuration>
        </plugin>
    </plugins>
</build>

问题是Flyway可以很好地创建数据库,但是当轮到jOOQ使用数据库生成代码时,它失败了:

Caused by: org.hsqldb.HsqlException: Database lock acquisition failure: lockFile: org.hsqldb.persist.LockFile@1096ec89[file =...db/db.lck, exists=true, locked=false, valid=false, ] method: checkHeartbeat read: 2015-02-09 03:56:15 heartbeat - read: -863 ms.
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.persist.LockFile.newLockFileLock(Unknown Source)
at org.hsqldb.persist.Logger.acquireLock(Unknown Source)
at org.hsqldb.persist.Logger.open(Unknown Source)
at org.hsqldb.Database.reopen(Unknown Source)
at org.hsqldb.Database.open(Unknown Source)
at org.hsqldb.DatabaseManager.getDatabase(Unknown Source)
at org.hsqldb.DatabaseManager.newSession(Unknown Source)

问题的核心是Maven's plugins do not share the same classloader as the rest of the POM,必须再次指定JDBC驱动依赖。因此,我得到了一个新的驱动程序实例,它与 Flyway 已打开的已打开驱动程序冲突,而不是使用相同的驱动程序。

因此,解决方案可能存在许多不同的路径:

    Flyway 可以正确关闭数据库。显然 Flyway 在其插件中有一个解决方法来读取项目的类路径。 jOOQ 可以通过某种方式配置为读取项目的类路径。 可能有另一个数据库会更好。 你的!

【问题讨论】:

有点蹩脚:为一些 Maven 任务生成单独的 JVM。 最近另一位使用 Derby Embedded 的用户也遇到了同样的问题:github.com/jOOQ/jOOQ/issues/4007 记录在案,如果您没有使用 Flyway,here's another way to solve this problem with the sql-maven-plugin 【参考方案1】:

感谢蒂洛的指导。用 exec 替换 Flyway 插件可以工作,但我必须 create a simpler command line client 才能使其工作。

【讨论】:

以上是关于在 Maven 中使用带有 Flyway 和 jOOQ 的嵌入式数据库进行持续集成的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot Flyway Jooq Code gen maven 插件顺序

如何使用 flyway 跳过特定的迁移?

flyway-maven-plugin:如何一起执行多个数据库配置?

链接 Maven Flyway 命令

使用Maven的Flyway Enterprise Edition错误:无法解决插件

使用 Maven 的 Spring Boot 属性从命令行运行 flyway 命令