5

I'm trying to use jOOQ in my Micronaut application, and have the jOOQ DSLContext automatically provided as an injected bean to my constructor, but it is failing to find the bean.

I've configured my datasources in my application.yml to connect to my postgres db, and have declared my constructor as follows:

@Singleton
public class RepositoryImpl implements Repository
{
    private final DSLContext context;

    public RepositoryImpl(DSLContext context)
    {
        this.context = context;
    }
}

and my application.yml as:

datasources:
  default:
    url: "jdbc:postgresql://localhost:5432/my_db"
    username: "user"
    password: "password"
    driver-class-name: "org.postgresql.Driver"

I've included the following dependencies in my build.gradle

    compile 'io.micronaut.configuration:micronaut-jooq'
    runtime 'org.postgresql:postgresql:42.2.4'

I would expect that I can access the DSLContext and write queries within my RepositoryImpl class, but upon trying to use the implementation class, the code fails with the following exception:

Caused by: io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [org.jooq.DSLContext] exists. Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).

Has anyone been able to successfully have this bean used as described in the micronaut-sql guide here? https://micronaut-projects.github.io/micronaut-sql/snapshot/guide/index.html#jooq

beerye
  • 253
  • 3
  • 15

1 Answers1

0

DSLContext exists on org.jooq.Configuration, so first of all somehow you have to instantiate the latter one.

You could define a class annotated with @Factory and inject a javax.sql.DataSource into its constructor which holds the Micronaut datasource config. After that you should define a method (annotated with @Singleton) in this class, and this method should return an org.jooq.Configuration. Inside this method you can configure jOOQ, basically you can use DefaultConfiguration(), but you have to set your SQL dialect by calling setSQLDialect(SQLDialect.POSTGRES) on it, and you also have to set your datasource (set(datasource)), with the datasource injected into the class.

import io.micronaut.context.annotation.Factory;
import org.jooq.Configuration;
import org.jooq.SQLDialect;
import org.jooq.impl.DefaultConfiguration;

import javax.inject.Singleton;
import javax.sql.DataSource;

@Factory
public class JooqConfigurationFactory {
    private final DataSource dataSource;

    public JooqConfigurationFactory(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Singleton
    public Configuration configuration() {
        DefaultConfiguration configuration = new DefaultConfiguration();
        configuration.setSQLDialect(SQLDialect.POSTGRES);
        configuration.set(dataSource);

        return configuration;
    }
}

And your repository will look like this:

import org.jooq.Configuration;
import org.jooq.DSLContext;

public class ExampleRepository {
    private final DSLContext context;

    public ExampleRepository(Configuration config) {
        this.context = config.dsl();
    }
}
akobor
  • 91
  • 2
  • 2