'How to use postgres database when generate jooq by LiquibaseDatabase
There is pretty good guide how to use code generation from liquibase However by default it uses h2 database to create schema from migrations and then generate records. How to specify another database for liquibase migrations (for example, postgres)?
My solution (build.gradle.kts):
plugins {
java
id("nu.studer.jooq") version "7.1.1"
id("org.liquibase.gradle") version "2.1.1"
}
java {
sourceCompatibility = JavaVersion.VERSION_18
targetCompatibility = JavaVersion.VERSION_18
}
dependencies {
jooqGenerator("org.postgresql:postgresql:42.3.2")
jooqGenerator("org.slf4j:slf4j-jdk14:1.7.30")
jooqGenerator("org.testcontainers:postgresql:1.17.1")
liquibaseRuntime(files("src/main/resources"))
liquibaseRuntime("org.testcontainers:postgresql:1.17.1")
liquibaseRuntime("org.postgresql:postgresql:42.3.2")
liquibaseRuntime("org.liquibase:liquibase-core")
liquibaseRuntime("info.picocli:picocli:4.6.1")
liquibaseRuntime("ch.qos.logback:logback-core:1.2.3")
liquibaseRuntime(sourceSets.getByName("main").compileClasspath)
liquibaseRuntime(sourceSets.getByName("main").output)
}
liquibase {
activities.register("main") {
this.arguments = mapOf(
"logLevel" to "info",
"changeLogFile" to "db/migration/changelog-master.xml",
"url" to "jdbc:tc:postgresql:9.6.8:///postgres?TC_DAEMON=true",
"username" to "user",
"password" to "password",
"driver" to "org.testcontainers.jdbc.ContainerDatabaseDriver"
)
}
runList = "main"
}
tasks.withType<JooqGenerate> {
dependsOn(tasks.named("update"))
}
jooq {
version.set("3.16.6")
edition.set(nu.studer.gradle.jooq.JooqEdition.OSS)
configurations {
create("main") {
generateSchemaSourceOnCompilation.set(true)
jooqConfiguration.apply {
logging = org.jooq.meta.jaxb.Logging.WARN
jdbc.apply {
driver = "org.testcontainers.jdbc.ContainerDatabaseDriver"
url = "jdbc:tc:postgresql:9.6.8:///postgres?TC_DAEMON=true"
user = "user"
password = "password"
}
generator.apply {
name = "org.jooq.codegen.DefaultGenerator"
database.apply {
name = "org.jooq.meta.postgres.PostgresDatabase"
inputSchema = "public"
}
generate.apply {
isDeprecated = false
isRecords = true
isImmutablePojos = true
isFluentSetters = true
}
target.apply {
packageName = "com.example"
directory = "build/generated-src/jooq/main"
}
strategy.name = "org.jooq.codegen.DefaultGeneratorStrategy"
}
}
}
}
}
tasks.named<nu.studer.gradle.jooq.JooqGenerate>("generateJooq") {
(launcher::set)(javaToolchains.launcherFor {
languageVersion.set(JavaLanguageVersion.of(18))
})
}
Expectations:
after running code gen ./gradlew generateJooq first starts postgres testcontainer and liquibase apply migrations, after that starts jooq code generationReality:
after running code gen starts postgres testcontainer and liquibase apply migrations and then starts new testcontainer and jooq tries generate recordsIs there any solution to specify one postgres container for migrations and code gen?
Solution 1:[1]
Solution:
(build.gradle.kts)
plugins {
java
idea
id("nu.studer.jooq")
id("org.liquibase.gradle")
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.testcontainers:postgresql:1.17.1")
}
}
dependencies {
jooqGenerator("org.jooq:jooq-meta-extensions-liquibase")
jooqGenerator("org.postgresql:postgresql:42.3.2")
jooqGenerator("org.slf4j:slf4j-jdk14:1.7.30")
jooqGenerator("org.testcontainers:postgresql:1.17.1")
jooqGenerator(files("src/main/resources"))
liquibaseRuntime(files("src/main/resources"))
liquibaseRuntime(sourceSets.getByName("main").compileClasspath)
liquibaseRuntime(sourceSets.getByName("main").output)
liquibaseRuntime("org.liquibase:liquibase-core")
liquibaseRuntime("org.postgresql:postgresql")
liquibaseRuntime("info.picocli:picocli:4.6.1")
liquibaseRuntime("ch.qos.logback:logback-core:1.2.3")
}
// starting container
var postgres: JdbcDatabaseContainer<*> = PostgreSQLContainerProvider().newInstance("14-alpine")
postgres.start()
val containerStop by tasks.registering {
if (postgres.isRunning) {
println("STOPPING DATABASE CONTAINER")
postgres.stop()
}
}
tasks.named("update") {
doLast {
tasks.named("generateJooq").get()
}
}
tasks.withType<JooqGenerate> {
doLast {
containerStop.get()
}
}
liquibase {
activities.register("main") {
this.arguments = mapOf(
"logLevel" to "info",
"classpath" to "${projectDir}/",
"changeLogFile" to "db/migration/changelog-master.xml",
"url" to postgres.jdbcUrl,
"username" to postgres.username,
"password" to postgres.password,
"driver" to "org.postgresql.Driver"
)
}
runList = "main"
}
jooq {
version.set(jooqVersion)
edition.set(JooqEdition.OSS)
configurations {
create("main") {
generateSchemaSourceOnCompilation.set(true)
jooqConfiguration.apply {
logging = Logging.WARN
jdbc.apply {
driver = "org.postgresql.Driver"
url = postgres.jdbcUrl
user = postgres.username
password = postgres.password
}
generator.apply {
name = "org.jooq.codegen.DefaultGenerator"
database.apply {
name = "org.jooq.meta.postgres.PostgresDatabase"
inputSchema = "public"
excludes = "databasechangelog|databasechangeloglock"
}
generate.apply {
isDeprecated = false
isRecords = true
isImmutablePojos = true
isFluentSetters = true
}
target.apply {
packageName = "my.package.jooq"
directory = "build/generated-src/jooq/main"
}
strategy.name = "org.jooq.codegen.DefaultGeneratorStrategy"
}
}
}
}
}
./gradlew clean update build
Solution 2:[2]
On the official jOOQ blog, they wrote up a guide for Using Testcontainers to Generate jOOQ Code
Pointing the jOOQ code generator towards a live database used to be a bit of a challenge, which is why jOOQ offers alternative, connection-free code generation modes, including:
- The JPADatabase, if you have a pre-existing JPA entity based meta model.
- The XMLDatabase, if you have some form of XML version of your schema, which you can XSL transform to jOOQ’s format
- The LiquibaseDatabase, which simulates a Liquibase database migration and uses the simulated database output as a source for meta information of the code generator
But all of the above have the same limitation. You can’t really use many vendor-specific features, such as advanced stored procedures, data types, etc.
The article continues, and describes how you can use jOOQ as a Modern Approach Using Testcontainers, which may help with understanding the proper procedures for using jOOQ's LiquibaseDatabase command.
Here is some additional documentation:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | tabbyfoo |