Search code examples
javajooq

How to make JOOQ gradle script does not re-create classes for which the table has not changed?


I have this gradle script for auto generate JOOQ classes.

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath(
                'org.jooq:jooq:3.18.4',
                'org.jooq:jooq-codegen:3.18.4',
                'org.jooq:jooq-meta:3.18.4',
                'org.postgresql:postgresql:42.6.0'
        )
    }
}

apply plugin: 'java'
apply plugin: 'nu.studer.jooq'

import org.jooq.codegen.GenerationTool
import org.jooq.meta.jaxb.*

task generateJooq {
    def configuration = new Configuration()
            .withJdbc(
                    new Jdbc()
                            .withDriver('org.postgresql.Driver')
                            .withUrl('jdbc:postgresql://localhost:5432/test')
                            .withUser('postgres')
                            .withPassword('password'))
            .withGenerator(
                    new Generator()
                            .withDatabase(new Database().withExcludes("databasechangeloglock|databasechangelog").withInputSchema("public"))
                            .withGenerate(
                                    new Generate()
                                            .withRoutines(false)
                                            .withPojos(true)
                                            .withDaos(true)
                            ).withTarget(
                            new Target()
                                    .withPackageName('com.example.model.jooq')
                                    .withDirectory(projectDir.toString() + '/src/main/java')
                    ).withStrategy(
                            new Strategy()
                                    .withMatchers(
                                            new Matchers()
                                                    .withTables(
                                                            new MatchersTableType()
                                                                    .withTableIdentifier(
                                                                            new MatcherRule()
                                                                                    .withExpression('$0_Entity')
                                                                                    .withTransform(MatcherTransformType.UPPER)
                                                                    ).withPojoClass(new MatcherRule().withExpression('$0_Entity').withTransform(MatcherTransformType.PASCAL))
                                                    )
                                    )
                    )
            )

    doLast {
        GenerationTool.generate(configuration)
    }
}

But when I make any changes to the tables (for example, do migration), I need to change my pojo, records, etc. classes. And when I run task generateJooq, it delete all classes and re-create their, and the problem is that all the lombok annotations (data, builder) disappear. I would like that when running the task, JOOQ would re-create only the changed tables, or even better if it did not re-create, and only added new fields in existing classes.


Solution

  • Thanks Lukas Eder, but I didn't figure it out :) and wrote this

    buildscript {
        repositories {
            mavenCentral()
        }
    
        dependencies {
            classpath(
                    'org.jooq:jooq:3.18.4',
                    'org.jooq:jooq-codegen:3.18.4',
                    'org.jooq:jooq-meta:3.18.4',
                    'org.postgresql:postgresql:42.6.0'
            )
        }
    }
    
    apply plugin: 'java'
    apply plugin: 'nu.studer.jooq'
    
    
    import org.jooq.codegen.GenerationTool
    import org.jooq.meta.jaxb.*
    
    import java.nio.charset.StandardCharsets
    import java.nio.file.Files
    import java.nio.file.Paths
    
    task generateJooq {
        var database = new Database().withExcludes("databasechangeloglock|databasechangelog").withInputSchema("public")
        def configuration = new Configuration()
                .withJdbc(
                        new Jdbc()
                                .withDriver('org.postgresql.Driver')
                                .withUrl('jdbc:postgresql://localhost:5432/test')
                                .withUser('postgres')
                                .withPassword('bigdata8'))
                .withGenerator(
                        new Generator()
                                .withDatabase(database)
                                .withGenerate(
                                        new Generate()
                                                .withRoutines(false)
                                                .withPojos(true)
                                                .withDaos(true)
                                )
                                .withTarget(
                                        new Target()
                                                .withPackageName('com.example.model.jooq')
                                                .withDirectory(projectDir.toString() + '/src/main/java')
                                )
                                .withStrategy(
                                        new Strategy()
                                                .withMatchers(
                                                        new Matchers()
                                                                .withTables(
                                                                        new MatchersTableType()
                                                                                .withTableIdentifier(
                                                                                        new MatcherRule()
                                                                                                .withExpression('$0_Entity')
                                                                                                .withTransform(MatcherTransformType.UPPER)
                                                                                ).withPojoClass(new MatcherRule().withExpression('$0_Entity').withTransform(MatcherTransformType.PASCAL))
                                                                )
                                                )
                                )
                )
    
    
        doLast {
            GenerationTool.generate(configuration)
    
            Files.walk(Paths.get(srcDir() + 'com/example/model/jooq/tables/pojos'))
                    .filter(path -> Files.isRegularFile(path))
                    .forEach(path -> {
                        List<String> list = Files.readAllLines(path)
    
                        boolean importAdded = false
                        boolean annotationsAdded = false
                        for (int i = 1; i < list.size(); i++) {
                            if (list.get(i - 1).startsWith("import") && list.get(i) == "") {
                                list.add(i + 1, "import lombok.Builder;")
                                i += 2
                                importAdded = true
                            }
                            if (importAdded) {
                                if (list.get(i).startsWith("public class")) {
                                    list.add(i - 1, "@Builder")
                                    annotationsAdded = true
                                    break
                                }
                            }
                        }
    
                        if (!importAdded || !annotationsAdded) {
                            throw new RuntimeException()
                        }
    
                        Files.write(path, list, StandardCharsets.UTF_8)
                    })
        }
    }
    
    String srcDir() {
        return projectDir.path + "/src/main/java/"
    }