How to use Spring boot, JOOQ and Flyway together? - java

So, let's consider a general Spring boot application, which uses JOOQ for database database access, and Flyway for database migration. The project uses gradle for dependency management.
I want the following things:
Run my application in docker. So, I want to use only in environment variables (https://12factor.net/config). Hence, I don't know, how to configure both spring boot application properties (database login and password) and gradle JOOQ plugin database login and password.
Automatic generation JOOQ classes. Flyway migration runs, when an application has started. But JOOQ generates code in gradle build task. So, we see wrong order of tasks execution.

I have a very similar setup, but resorted to manual action to generate Jooq classes.
I need them for development, so it makes no sense for me to delay the generation till target environment.
I decided to run a local dB for development purposes.
I run it in docker, but this is a detail in the entire setup.
When I have a new migration, I run it with flyway grade plugin against the local dB. Then I regenerate Jooq classes with grade Jooq plugin.
When the app is deployed in the target environment, I rely on flyway to run migration on startup. I have matching Jooq classes packaged, so everything works smoothly.

The jOOQ GitHub project has an example project that uses jOOQ with Spring Boot and the sql-maven-plugin.
You can easily replace the sql-maven-plugin by the Flyway plugin as demonstrated in the jOOQ/Flyway example project or this blog post.
On a related note, in case you're using one of the commercial distributions of jOOQ with Spring Boot, this is documented in this blog post here.

There is the following gradle task, which requires flyway, otj-pg-embedded, jooq and postgresql driver:
import com.opentable.db.postgres.embedded.*
import org.flywaydb.core.*
import org.jooq.codegen.*
tasks.named("compileKotlin") {
doFirst {
//create embedded postgresql
EmbeddedPostgres.builder().setPort(5400).start().use {
//migrate embedded posrtgresql
Flyway.configure()
.locations("filesystem:$projectDir/migrations/")
.schemas("public")
.dataSource(it.postgresDatabase)
.load()
.migrate()
//generate jooq classes
GenerationTool.generate("some xml for jooq")
}
}
}
The source is https://gist.github.com/whyoleg/63195b60eb85e8fe2114b30f28b892ef

Related

Disable flyway for Non springboot project - Normal maven -spring project

I want to disable flyway for a certain environment but can't find a way to do it
Below are the version of stack
Spring - 3.2
Flyway - 4.0.3
Mysql - 5.6.3
Exploring flyway and open to any approach for disabling to
Looked for a lot, but all I can find is how to disable it for spring-boot.
Can anyone please help?
Also I want to use core spring this features through spring and maven, and not via java classes
If you could update Spring to version 4 you could use the #Conditional with a custom Condition to create the Flyway bean conditionally.

What are the pros/cons of using the Gradle integration vs Spring Boot integration for Flyway?

Flyway has several integration options.
I'm trying to determine what the pros/cons are of using the Gradle integration vs the Spring Boot integration given that your project is already using both Spring Boot and Gradle.
The only thing I can think of is that if you want to be able to do migrations without starting the application or want to save time by not migrating every time you start the app then the Gradle choice could be better.
Think of it as build time vs run time.
In general you will build an artifact once and deploy it to many environments, so run time is a much better fit.
However sometimes build time makes sense. This is primarily for situations where you need a fully migrated database as part of the build, in order to for example generate code based on the structure of that database using frameworks like jOOQ or QueryDSL.

How to handle DCL in Flyway migration scripts?

I have a postgres database that has users and roles already defined. There are multiple schemas in this database that are all controlled via different projects/flyway scripts. I am working on adding Flyway integration into a new project where we will use an embedded Postgres instance for testing.
Since none of these users/roles will exist on this instance, they need to be created in a migration script. However, since these users/roles will already exist in my operational databases, the migrations will fail when they attempt to create the roles.
I already considered writing a function for this, but then the function would have to be included in any project that uses the embedded Postgres and would have to be maintained across multiple code bases. This seems very sloppy. Can anyone recommend a way for me to handle these DCL operations using Flyway that will work with the embedded approach as well as my operational databases?
In a previous project we use for this approach a set of additional Flyway migration scripts. These scripts we add to the test environment classpath.
We used this for a Flyway version before the feature of Callback and repeatable migrations were added.
Add a callback configuration for your Test environment and you add in the before or after migration phase your user and roles.
Third solution use repeatable migration scripts for your user and roles setup see https://flywaydb.org/documentation/migration/repeatable. Use this scripts in production and test. But in this case your sql must done correct and repeatable otherwise you will break your production environment.

Using DBDeploy in Gradle with hibernate as the ORM

I am looking to use a versioned database migrations tool like DBdeploy in a java project which uses Hibernate as the ORM and uses Gradle as the build system. I am unable to lookup any documentation on running DBDeploy on Gradle. Also is there a Hibernate based migrations manager, which can understand schema changes by looking at changes in Hibernate classes/definitions?
Since dbdeploy has an Ant task, it should be straightforward to use from Gradle. See Using Ant Tasks in the Gradle User Guide.
I am unable to lookup any documentation on running DBDeploy on Gradle.
Almost any build system can likely call either the ant task or the command-line interface for dbdeploy.
Also is there a Hibernate based migrations manager, which can understand schema changes by looking at changes in Hibernate classes/definitions?
You might want to look at Liquibase. I haven't actually used it (I've used dbdeploy), but it has hibernate integration that looks like what you want.
this post shows how to use DBDeploy in Gradle:
http://blog.codeborne.com/2012/09/using-dbdeploy-in-gradle.html

How do we migrate/update the database schema in Grails?

We've been working with Grails for a while and my Team Lead raised some questions about the Grails ORM (GORM):
How do we maintain the database schema once we have moved to production?
Can we update the database schema with Grails?
If the schema is updated, will the changes be automatically reflected / does the framework take care of this?
Is there any plugin for Grails that will allow us to update the schema without headaches?
I recently released the official Grails plugin for database migrations - see http://grails.org/plugin/database-migration and the docs at http://grails-plugins.github.com/grails-database-migration/docs/manual/index.html
I'm working with the author of Liquibase on this, so the older liquibase plugin is now deprecated and the new one should be used since it uses the latest version of Liquibase (2.0) and is officially supported by SpringSource. See http://blog.liquibase.org/2011/01/new-standard-liquibase-plugin-grails-database-migration.html for his announcement.
Ask usage questions on the Grails User mailing list (signup from http://grails.org/Mailing+lists) or the new plugin forum at http://grails-plugins.847840.n3.nabble.com/ or email the author directly :)
Remove dbCreate parameter in DataSource.groovy for your production environment - this will stop GORM from auto-updating DB schema.
Sure. Use LiquiBase plugin.
GORM can do it with dbCreate='update', but it's strongly not recommended. For instance, if you rename a field, GORM/LiquiBase can never determine that you have to migrate the data, and not just drop+create.
In one line: grails db-diff to generate LiquiBase's changelog.xml, and grails migrate -Dgrails.env=<whatever environment> to apply it to respective db server.
While the "auto create" functionality is ok to get a project up and running I find liquibase the best way to keep the db up-to-date. There is a grails plugin and I believe work is under way on a DSL too.
So, create a baseline schema (you could use liquibase's generate-changelog) then make all future changes through liquibase and it will manage the updates, rollbacks and even some db interop for you. You can set your DataSource.groovy config to verify and grails will not start up if the schema does not match the domain config:
environments {
development {
dataSource {
dbCreate = "validate"
You may also be interested in the liquibase-runner plugin to run your migrations on application start.

Categories

Resources