gimg1
gimg1

Reputation: 1167

jOOQ Custom Pojo & DAO Generation

Problem

I'm having some issues configuring mapping to custom Pojos during code generation.

Question

I have implemented RecordMapperProvider but wondering how I register it to be used during the code generation phase, or even if that is possible?

More Context

I love the fact that Pojos & DAOs are generated but I want to define the Pojo myself without too much configuration code. I am using ModelMapper to map from Type to Target:

@Override
public <R extends Record, E> RecordMapper<R, E> provide(RecordType<R> recordType,
                                                        Class<? extends E> type) {

    if (mapping.containsKey(type)) {
        return record -> modelMapper.map(mapping.get(type), type);
    }

    return new DefaultRecordMapper<>(recordType, type);
}

If it helps, I am configuring jOOQ using a DefaultConfiguration object (which is a bean):

@Bean
public DefaultConfiguration configuration() {
    DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
    jooqConfiguration.setConnectionProvider(dataSourceConnectionProvider());
    jooqConfiguration.setExecuteListenerProvider(new DefaultExecuteListenerProvider(
            jooqToSpringExceptionTranslator()));
    jooqConfiguration.setSQLDialect(
            SQLDialect.valueOf(env.getRequiredProperty("jooq.sql.dialect")));
    jooqConfiguration.setRecordMapperProvider(new JooqRecordMapperFactory(modelMapper()));

    return jooqConfiguration;
}

And then for Code Generation I am configuring it in gradle:

jooq {
version = '3.10.5'
edition = 'OSS'

myDb(sourceSets.getByName("main")) {
    jdbc {
        driver = dbDriver
        url = dbUrl
        user = dbUsername
    }
    generator {
        name = 'org.jooq.util.JavaGenerator'
        strategy {
            name = 'org.jooq.util.DefaultGeneratorStrategy'
        }
        database {
            name = 'org.jooq.util.postgres.PostgresDatabase'
            inputSchema = dbSchema
        }
        generate {
            relations = true
            deprecated = false
            records = true
            immutablePojos = true
            fluentSetters = true
            daos = true
        }
        target {
            packageName = 'com.textiq.quinn.common.dao.model.generated'
        }
    }
}
}

I am sure there is a disconnect here between both configurations but I can't glean from the documentation how I synch these. Ideally I want jOOQ to generate Pojos (based on the mapping that ModelMapper provides in my implementation of RecordMapperProvider) and also have jOOQ provide the DAO's for these Pojos. Is this possible? The documentation states:

If you're using jOOQ's code generator, you can configure it to generate POJOs for you, but you're not required to use those generated POJOs. You can use your own. See the manual's section about POJOs with custom RecordMappers to see how to modify jOOQ's standard POJO mapping behaviour.

Source: https://www.jooq.org/doc/3.9/manual/sql-execution/fetching/pojos/

Which to me indicates the possibility of this but only leads me to implementing RecordMapperProvider and nothing after that.

Upvotes: 0

Views: 2359

Answers (2)

aarbor
aarbor

Reputation: 1534

I'm a few years late to the party, but I actually found a very simple way to do this. I'll admit that it's a little brittle, but you can refine it further to suit your needs.

  1. Create a new module in your gradle project, for example called jooq-generator
  2. Add jooq-codegen as a compileOnly dependency to the module
  3. Create a new class in the module:
public class Generator extends JavaGenerator {
    @Override
    public boolean generatePojos() {
        return false;
    }
}
  1. Create a new class in the module:

public class MyGeneratorStrategy extends DefaultGeneratorStrategy {
   @Override
   public String getJavaPackageName(Definition definition, Mode mode) {
       if (mode != Mode.POJO) {
           return super.getJavaPackageName(definition, mode);
       }
       return "com.example.my.model.package.prefix";
   }

}
  1. Add the module as a dependency to the jooqGenerator jooqGenerator project(":jooq-generator")
  2. Add your new classes to the jooq config
jooq {
    configurations {
        main {
            generationTool {
                generator {
                    name = 'com.example.my.package.name.Generator'
                    strategy {
                        name = 'com.example.my.package.name.MyGeneratorStrategy'
                    }
                }
            }
        }
    }
}
  1. The daos will now be generated using that package prefix for the POJOs instead of the generated package name.

Upvotes: 0

Lukas Eder
Lukas Eder

Reputation: 220762

I have implemented RecordMapperProvider but wondering how I register it to be used during the code generation phase, or even if that is possible?

No, it's not possible, out of the box.

I love the fact that Pojos & DAOs are generated but I want to define the Pojo myself without too much configuration code

Then, I suggest turning off the generation of POJOs and DAOs and roll your own. Either, create manual implementations of DAOs, or extend the JavaGenerator to do so.

Upvotes: 2

Related Questions