Shorn
Shorn

Reputation: 21476

How to configure JOOQ settings using Spring-Boot config?

I want to tell JOOQ not to quote the identifiers in the SQL it generates as per the answer here: https://stackoverflow.com/a/28146263/924597

But given I'm letting Spring Boot autoconfigure JOOQ - where do I put this setting?

It seems like the basic spring boot config only supports setting spring.jooq.sql-dialect in the application.properties, as shown in the JOOQ-spring-boot-example.

I tried putting spring.jooq.renderNameStyle=AS_IS in the application.properties but it didn't have any effect on the SQL.

Is there was way customise the Spring boot JOOQ configuration without having to configure JOOQ myself?

I am using SpringBoot 2.1.7.RELEASE and JOOQ 3.11.12.

Upvotes: 5

Views: 6589

Answers (4)

Jens Møller
Jens Møller

Reputation: 609

You can also provide a Settings bean (that returns an org.jooq.conf.Settings object).

Example that solves the original question:

@Configuration
public class JooqConfig {

    @Bean
    Settings jooqSettings() {
        return new Settings().withRenderNameStyle(RenderNameStyle.AS_IS);
    }
}

The Spring Boot documentation is currently missing that, but I checked the source and tested it locally, I have created a PR to fix it.

From spring boot 3.0 you need to use the DefaultConfigurationCustomizer, for instance like:

@Configuration
public class JooqConfig {

    @Bean
    public DefaultConfigurationCustomizer jooqDefaultConfigurationCustomizer() {
        return c -> c.settings().withRenderNameStyle(RenderNameStyle.AS_IS);
    }
}

More information is available on the jooq blog.

Upvotes: 8

Andrei Nevedomskii
Andrei Nevedomskii

Reputation: 321

Starting with Spring Boot 3, the answer provided by Jens wouldn't work anymore, instead one can use org.springframework.boot.autoconfigure.jooq.DefaultConfigurationCustomizer, like this (example in Kotlin):

    @Bean
    fun jooqConfigurationCustomizer(): DefaultConfigurationCustomizer =
        DefaultConfigurationCustomizer { config ->
            config.setSettings(
                Settings()
                    .withBindOffsetDateTimeType(true)
                    .withRenderQuotedNames(RenderQuotedNames.EXPLICIT_DEFAULT_UNQUOTED)
            )
        }

Upvotes: 5

Shorn
Shorn

Reputation: 21476

Note that the answer from Lukas worked for configuring the rendering style, but resulted in JOOQ no longer participating in Spring transaction handling.

Below is the code I've added to my project to customise the identifier rendering.

import org.jooq.DSLContext;
import org.jooq.SQLDialect;
import org.jooq.conf.RenderNameStyle;
import org.jooq.conf.Settings;
import org.jooq.impl.DataSourceConnectionProvider;
import org.jooq.impl.DefaultConfiguration;
import org.jooq.impl.DefaultDSLContext;
import org.jooq.impl.DefaultExecuteListenerProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jooq.JooqExceptionTranslator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;


/**
 Override spring-boot config so JOOQ settings can be customised.
 See: https://stackoverflow.com/q/57542573/924597

 Spring-boot config taken from:
 https://github.com/eugenp/tutorials/blob/master/spring-jooq/src/test/java/com/baeldung/jooq/springboot/InitialConfiguration.java
*/
@Component
@Configuration
public class JooqConfig {
  @Autowired DataSource dataSource;

  @Bean
  public DataSourceConnectionProvider connectionProvider() {
    return new DataSourceConnectionProvider(
      new TransactionAwareDataSourceProxy(dataSource));
  }

  @Bean
  public DSLContext dsl() {
    return new DefaultDSLContext(configuration());
  }

  public DefaultConfiguration configuration() {
    DefaultConfiguration config = new DefaultConfiguration();
    config.set(connectionProvider());
    config.set(SQLDialect.POSTGRES);
    config.set(new Settings().
      withRenderNameStyle(RenderNameStyle.AS_IS ));
    config.set(new DefaultExecuteListenerProvider(
      new JooqExceptionTranslator() ));
    return config;
  }
}

Note: The above code appears to work, but results in my IDE telling me that I have multiple beans registered for the DSLContext type. I also added JooqAutoConfigration to my list of excluded spring-boot auto-config.

@EnableAutoConfiguration(exclude = {
  SecurityAutoConfiguration.class,
  DataSourceAutoConfiguration.class,
  JooqAutoConfiguration.class
})

Upvotes: 8

Lukas Eder
Lukas Eder

Reputation: 220932

Spring Boot is a toolkit to get you started with some set of dependencies as quickly as possible. This doesn't mean that you should do everything via Spring Boot. Spring Boot cannot possibly maintain a flag corresponding to every single third party library's flag out there.

The reason why spring boot supports spring.jooq.sql-dialect is because in some cases, jOOQ cannot auto-detect the dialect from the JDBC Connection or DataSource, so it is a necessity for Spring Boot to provide that information to jOOQ. The Settings.renderNameStyle, on the other hand, is a much more advanced setting that Spring Boot doesn't need to know in order to get a minimal configuration started.

Hence, as soon as you're starting to use more sophisticated library settings / flags, you will need to configure the library yourself. In this case, you could provide the DSLContext bean programmatically, or through various other Spring-idiomatic ways, e.g.

@Autowired DataSource ds;

@Bean
public DSLContext ctx() {
    DSL.using(ds, SQLDialect.ORACLE, new Settings().withRenderNameStyle(AS_IS));
}

And then inject that DSLContext everywhere.

Upvotes: 1

Related Questions