diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml
index 7de84e78c8..4ff4029fc0 100644
--- a/spring-boot-autoconfigure/pom.xml
+++ b/spring-boot-autoconfigure/pom.xml
@@ -510,6 +510,11 @@
aspectjweavertrue
+
+ org.jooq
+ jooq
+ true
+ org.springframework.boot
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java
new file mode 100644
index 0000000000..c4e747e3e8
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.jooq;
+
+import javax.sql.DataSource;
+
+import org.jooq.ConnectionProvider;
+import org.jooq.DSLContext;
+import org.jooq.ExecuteListenerProvider;
+import org.jooq.RecordListenerProvider;
+import org.jooq.RecordMapperProvider;
+import org.jooq.SQLDialect;
+import org.jooq.TransactionProvider;
+import org.jooq.VisitListenerProvider;
+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.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.util.StringUtils;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for JOOQ.
+ *
+ * @author Andreas Ahlenstorf
+ * @since 1.3.0
+ */
+@Configuration
+@ConditionalOnClass(DSLContext.class)
+@ConditionalOnBean(DataSource.class)
+@AutoConfigureAfter(DataSourceAutoConfiguration.class)
+public class JooqAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean(DataSourceConnectionProvider.class)
+ public DataSourceConnectionProvider dataSourceConnectionProvider(DataSource dataSource) {
+ return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(
+ dataSource));
+ }
+
+ @Bean
+ @ConditionalOnBean(PlatformTransactionManager.class)
+ public TransactionProvider transactionProvider(PlatformTransactionManager txManager) {
+ return new SpringTransactionProvider(txManager);
+ }
+
+ @Bean
+ public ExecuteListenerProvider jooqExceptionTranslatorExecuteListenerProvider() {
+ return new DefaultExecuteListenerProvider(new JooqExceptionTranslator());
+ }
+
+ @Configuration
+ @ConditionalOnMissingBean(DSLContext.class)
+ @EnableConfigurationProperties(JooqProperties.class)
+ public static class DslContextConfiguration {
+
+ @Autowired
+ private JooqProperties properties = new JooqProperties();
+
+ @Autowired
+ private ConnectionProvider connectionProvider;
+
+ @Autowired(required = false)
+ private TransactionProvider transactionProvider;
+
+ @Autowired(required = false)
+ private RecordMapperProvider recordMapperProvider;
+
+ @Autowired(required = false)
+ private Settings settings;
+
+ @Autowired(required = false)
+ private RecordListenerProvider[] recordListenerProviders;
+
+ @Autowired
+ private ExecuteListenerProvider[] executeListenerProviders;
+
+ @Autowired(required = false)
+ private VisitListenerProvider[] visitListenerProviders;
+
+ @Bean
+ public DefaultDSLContext dslContext(org.jooq.Configuration configuration) {
+ return new DefaultDSLContext(configuration);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean(org.jooq.Configuration.class)
+ public DefaultConfiguration jooqConfiguration() {
+ DefaultConfiguration configuration = new DefaultConfiguration();
+ if (!StringUtils.isEmpty(this.properties.getSqlDialect())) {
+ configuration.set(SQLDialect.valueOf(this.properties.getSqlDialect()));
+ }
+ configuration.set(this.connectionProvider);
+ if (this.transactionProvider != null) {
+ configuration.set(this.transactionProvider);
+ }
+ if (this.recordMapperProvider != null) {
+ configuration.set(this.recordMapperProvider);
+ }
+ if (this.settings != null) {
+ configuration.set(this.settings);
+ }
+ configuration.set(this.recordListenerProviders);
+ configuration.set(this.executeListenerProviders);
+ configuration.set(this.visitListenerProviders);
+ return configuration;
+ }
+
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqExceptionTranslator.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqExceptionTranslator.java
new file mode 100644
index 0000000000..addc5857ea
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqExceptionTranslator.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.jooq;
+
+import java.sql.SQLException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jooq.ExecuteContext;
+import org.jooq.SQLDialect;
+import org.jooq.impl.DefaultExecuteListener;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
+import org.springframework.jdbc.support.SQLExceptionTranslator;
+import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
+
+/**
+ * Transforms {@link java.sql.SQLException} into a Spring-specific @{link
+ * DataAccessException}.
+ *
+ * @author Lukas Eder
+ * @author Andreas Ahlenstorf
+ * @author Phillip Webb
+ */
+class JooqExceptionTranslator extends DefaultExecuteListener {
+
+ // Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
+
+ private static final Log logger = LogFactory.getLog(JooqExceptionTranslator.class);
+
+ @Override
+ public void exception(ExecuteContext context) {
+ SQLExceptionTranslator translator = getTranslator(context);
+ // The exception() callback is not only triggered for SQL exceptions but also for
+ // "normal" exceptions. In those cases sqlException() returns null.
+ SQLException exception = context.sqlException();
+ while (exception != null) {
+ handle(context, translator, exception);
+ exception = exception.getNextException();
+ }
+ }
+
+ private SQLExceptionTranslator getTranslator(ExecuteContext context) {
+ SQLDialect dialect = context.configuration().dialect();
+ if (dialect != null) {
+ return new SQLErrorCodeSQLExceptionTranslator(dialect.name());
+ }
+ return new SQLStateSQLExceptionTranslator();
+ }
+
+ /**
+ * Handle a single exception in the chain. SQLExceptions might be nested multiple
+ * levels deep. The outermost exception is usually the least interesting one
+ * ("Call getNextException to see the cause."). Therefore the innermost exception is
+ * propagated and all other exceptions are logged.
+ * @param context the execute context
+ * @param translator the exception translator
+ * @param exception the exception
+ */
+ private void handle(ExecuteContext context, SQLExceptionTranslator translator,
+ SQLException exception) {
+ DataAccessException translated = translate(context, translator, exception);
+ if (exception.getNextException() == null) {
+ context.exception(translated);
+ }
+ else {
+ logger.error("Execution of SQL statement failed.", translated);
+ }
+ }
+
+ private DataAccessException translate(ExecuteContext context,
+ SQLExceptionTranslator translator, SQLException exception) {
+ return translator.translate("jOOQ", context.sql(), exception);
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java
new file mode 100644
index 0000000000..c68961bb71
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.jooq;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for the JOOQ database library.
+ *
+ * @author Andreas Ahlenstorf
+ * @since 1.3.0
+ */
+@ConfigurationProperties(prefix = "spring.jooq")
+public class JooqProperties {
+
+ /**
+ * SQLDialect JOOQ used when communicating with the configured datasource, e.g.
+ * "POSTGRES".
+ */
+ private String sqlDialect;
+
+ public String getSqlDialect() {
+ return this.sqlDialect;
+ }
+
+ public void setSqlDialect(String sqlDialect) {
+ this.sqlDialect = sqlDialect;
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransaction.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransaction.java
new file mode 100644
index 0000000000..c766d20a69
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransaction.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.jooq;
+
+import org.jooq.Transaction;
+import org.springframework.transaction.TransactionStatus;
+
+/**
+ * Adapts a Spring transaction for JOOQ.
+ *
+ * @author Lukas Eder
+ * @author Andreas Ahlenstorf
+ * @author Phillip Webb
+ */
+class SpringTransaction implements Transaction {
+
+ // Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
+
+ private final TransactionStatus transactionStatus;
+
+ public SpringTransaction(TransactionStatus transactionStatus) {
+ this.transactionStatus = transactionStatus;
+ }
+
+ public TransactionStatus getTxStatus() {
+ return this.transactionStatus;
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransactionProvider.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransactionProvider.java
new file mode 100644
index 0000000000..bfe80f1fc0
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransactionProvider.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.jooq;
+
+import org.jooq.TransactionContext;
+import org.jooq.TransactionProvider;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
+
+/**
+ * Allows Spring Transaction to be used with JOOQ.
+ *
+ * @author Lukas Eder
+ * @author Andreas Ahlenstorf
+ * @author Phillip Webb
+ */
+class SpringTransactionProvider implements TransactionProvider {
+
+ // Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
+
+ private final PlatformTransactionManager transactionManager;
+
+ SpringTransactionProvider(PlatformTransactionManager transactionManager) {
+ this.transactionManager = transactionManager;
+ }
+
+ @Override
+ public void begin(TransactionContext context) {
+ TransactionDefinition definition = new DefaultTransactionDefinition(
+ TransactionDefinition.PROPAGATION_NESTED);
+ TransactionStatus status = this.transactionManager.getTransaction(definition);
+ context.transaction(new SpringTransaction(status));
+ }
+
+ @Override
+ public void commit(TransactionContext ctx) {
+ this.transactionManager.commit(getTransactionStatus(ctx));
+ }
+
+ @Override
+ public void rollback(TransactionContext ctx) {
+ this.transactionManager.rollback(getTransactionStatus(ctx));
+ }
+
+ private TransactionStatus getTransactionStatus(TransactionContext ctx) {
+ SpringTransaction transaction = (SpringTransaction) ctx.transaction();
+ return transaction.getTxStatus();
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/package-info.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/package-info.java
new file mode 100644
index 0000000000..0ee259b983
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Auto-configuration for JOOQ.
+ */
+package org.springframework.boot.autoconfigure.jooq;
\ No newline at end of file
diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
index 05834600d2..8fe06c5c4c 100644
--- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -39,6 +39,7 @@ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchDataAutoConfig
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
+org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfigurationTests.java
new file mode 100644
index 0000000000..b2003bbf9b
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfigurationTests.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.jooq;
+
+import javax.sql.DataSource;
+
+import org.hamcrest.Matcher;
+import org.jooq.DSLContext;
+import org.jooq.ExecuteListener;
+import org.jooq.ExecuteListenerProvider;
+import org.jooq.Record;
+import org.jooq.RecordListener;
+import org.jooq.RecordListenerProvider;
+import org.jooq.RecordMapper;
+import org.jooq.RecordMapperProvider;
+import org.jooq.RecordType;
+import org.jooq.SQLDialect;
+import org.jooq.TransactionalRunnable;
+import org.jooq.VisitListener;
+import org.jooq.VisitListenerProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
+import org.springframework.boot.test.EnvironmentTestUtils;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests for {@link JooqAutoConfiguration}.
+ *
+ * @author Andreas Ahlenstorf
+ * @author Phillip Webb
+ */
+public class JooqAutoConfigurationTests {
+
+ private static final String[] NO_BEANS = {};
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+
+ @Before
+ public void init() {
+ EnvironmentTestUtils.addEnvironment(this.context,
+ "spring.datasource.name:jooqtest");
+ EnvironmentTestUtils.addEnvironment(this.context, "spring.jooq.sql-dialect:H2");
+ }
+
+ @After
+ public void close() {
+ if (this.context != null) {
+ this.context.close();
+ }
+ }
+
+ @Test
+ public void noDataSource() throws Exception {
+ registerAndRefresh(JooqAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ assertEquals(0, this.context.getBeanNamesForType(DSLContext.class).length);
+ }
+
+ @Test
+ public void jooqWithoutTx() throws Exception {
+ registerAndRefresh(JooqDataSourceConfiguration.class,
+ JooqAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
+ assertThat(getBeanNames(PlatformTransactionManager.class), equalTo(NO_BEANS));
+ assertThat(getBeanNames(SpringTransactionProvider.class), equalTo(NO_BEANS));
+ DSLContext dsl = this.context.getBean(DSLContext.class);
+ dsl.execute("create table jooqtest (name varchar(255) primary key);");
+ dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;",
+ equalTo("0")));
+ dsl.transaction(new ExecuteSql(dsl, "insert into jooqtest (name) values ('foo');"));
+ dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;",
+ equalTo("1")));
+ try {
+ dsl.transaction(new ExecuteSql(dsl,
+ "insert into jooqtest (name) values ('bar');",
+ "insert into jooqtest (name) values ('foo');"));
+ fail("An DataIntegrityViolationException should have been thrown.");
+ }
+ catch (DataIntegrityViolationException ex) {
+ }
+ dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;",
+ equalTo("2")));
+ }
+
+ @Test
+ public void jooqWithTx() throws Exception {
+ registerAndRefresh(JooqDataSourceConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class, TxManagerConfiguration.class,
+ JooqAutoConfiguration.class);
+ this.context.getBean(PlatformTransactionManager.class);
+ DSLContext dsl = this.context.getBean(DSLContext.class);
+ assertEquals(SQLDialect.H2, dsl.configuration().dialect());
+ dsl.execute("create table jooqtest_tx (name varchar(255) primary key);");
+ dsl.transaction(new AssertFetch(dsl,
+ "select count(*) as total from jooqtest_tx;", equalTo("0")));
+ dsl.transaction(new ExecuteSql(dsl,
+ "insert into jooqtest_tx (name) values ('foo');"));
+ dsl.transaction(new AssertFetch(dsl,
+ "select count(*) as total from jooqtest_tx;", equalTo("1")));
+ try {
+ dsl.transaction(new ExecuteSql(dsl,
+ "insert into jooqtest (name) values ('bar');",
+ "insert into jooqtest (name) values ('foo');"));
+ fail("A DataIntegrityViolationException should have been thrown.");
+ }
+ catch (DataIntegrityViolationException ex) {
+ }
+ dsl.transaction(new AssertFetch(dsl,
+ "select count(*) as total from jooqtest_tx;", equalTo("1")));
+ }
+
+ @Test
+ public void customProvidersArePickedUp() {
+ registerAndRefresh(JooqDataSourceConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class, TxManagerConfiguration.class,
+ TestRecordMapperProvider.class, TestRecordListenerProvider.class,
+ TestExecuteListenerProvider.class, TestVisitListenerProvider.class,
+ JooqAutoConfiguration.class);
+ DSLContext dsl = this.context.getBean(DSLContext.class);
+ assertEquals(TestRecordMapperProvider.class, dsl.configuration()
+ .recordMapperProvider().getClass());
+ assertThat(dsl.configuration().recordListenerProviders().length, equalTo(1));
+ assertThat(dsl.configuration().executeListenerProviders().length, equalTo(2));
+ assertThat(dsl.configuration().visitListenerProviders().length, equalTo(1));
+ }
+
+ private void registerAndRefresh(Class>... annotatedClasses) {
+ this.context.register(annotatedClasses);
+ this.context.refresh();
+ }
+
+ private String[] getBeanNames(Class> type) {
+ return this.context.getBeanNamesForType(type);
+ }
+
+ private static class AssertFetch implements TransactionalRunnable {
+
+ private final DSLContext dsl;
+
+ private final String sql;
+
+ private final Matcher super String> matcher;
+
+ public AssertFetch(DSLContext dsl, String sql, Matcher super String> matcher) {
+ this.dsl = dsl;
+ this.sql = sql;
+ this.matcher = matcher;
+ }
+
+ @Override
+ public void run(org.jooq.Configuration configuration) throws Exception {
+ assertThat(this.dsl.fetch(this.sql).getValue(0, 0).toString(), this.matcher);
+ }
+
+ }
+
+ private static class ExecuteSql implements TransactionalRunnable {
+
+ private final DSLContext dsl;
+
+ private final String[] sql;
+
+ public ExecuteSql(DSLContext dsl, String... sql) {
+ this.dsl = dsl;
+ this.sql = sql;
+ }
+
+ @Override
+ public void run(org.jooq.Configuration configuration) throws Exception {
+ for (String statement : this.sql) {
+ this.dsl.execute(statement);
+ }
+ }
+
+ }
+
+ @Configuration
+ protected static class JooqDataSourceConfiguration {
+
+ @Bean
+ public DataSource jooqDataSource() {
+ return DataSourceBuilder.create().url("jdbc:hsqldb:mem:jooqtest")
+ .username("sa").build();
+ }
+
+ }
+
+ @Configuration
+ protected static class TxManagerConfiguration {
+
+ @Bean
+ public PlatformTransactionManager transactionManager(DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+ }
+
+ }
+
+ protected static class TestRecordMapperProvider implements RecordMapperProvider {
+
+ @Override
+ public RecordMapper provide(RecordType recordType,
+ Class extends E> aClass) {
+ return null;
+ }
+
+ }
+
+ protected static class TestRecordListenerProvider implements RecordListenerProvider {
+
+ @Override
+ public RecordListener provide() {
+ return null;
+ }
+
+ }
+
+ protected static class TestExecuteListenerProvider implements ExecuteListenerProvider {
+
+ @Override
+ public ExecuteListener provide() {
+ return null;
+ }
+
+ }
+
+ protected static class TestVisitListenerProvider implements VisitListenerProvider {
+
+ @Override
+ public VisitListener provide() {
+ return null;
+ }
+
+ }
+
+}
diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml
index 27afee588a..f686060fb7 100644
--- a/spring-boot-dependencies/pom.xml
+++ b/spring-boot-dependencies/pom.xml
@@ -100,6 +100,7 @@
2.8.11.3.120141113
+ 3.6.22.0.01.24.12
@@ -318,6 +319,11 @@
spring-boot-starter-jetty1.3.0.BUILD-SNAPSHOT
+
+ org.springframework.boot
+ spring-boot-starter-jooq
+ 1.3.0.BUILD-SNAPSHOT
+ org.springframework.bootspring-boot-starter-jta-atomikos
@@ -1477,6 +1483,21 @@
json${json.version}
+
+ org.jooq
+ jooq
+ ${jooq.version}
+
+
+ org.jooq
+ jooq-meta
+ ${jooq.version}
+
+
+ org.jooq
+ jooq-codegen
+ ${jooq.version}
+ org.liquibaseliquibase-core
@@ -1836,6 +1857,11 @@
+
+ org.jooq
+ jooq-codegen-maven
+ ${jooq.version}
+ org.springframework.bootspring-boot-maven-plugin
diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
index 6395486b44..d81190c560 100644
--- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
+++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
@@ -340,6 +340,9 @@ content into your application; rather pick only the properties that you need.
spring.jta.log-dir= # transaction log dir
spring.jta.*= # technology specific configuration
+ # JOOQ ({sc-spring-boot-autoconfigure}/jooq/JooqAutoConfiguration.{sc-ext}[JooqAutoConfiguration])
+ spring.jooq.sql-dialect=
+
# ATOMIKOS
spring.jta.atomikos.connectionfactory.borrow-connection-timeout=30 # Timeout, in seconds, for borrowing connections from the pool
spring.jta.atomikos.connectionfactory.ignore-session-transacted-flag=true # Whether or not to ignore the transacted flag when creating session
diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
index 14a9becd50..a94e15d3b4 100644
--- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
+++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
@@ -1998,6 +1998,114 @@ Hibernate autoconfig is active because the `ddl-auto` settings are more fine-gra
+[[boot-features-jooq]]
+== Using jOOQ
+Java Object Oriented Querying (http://www.jooq.org/[jOOQ]) is a popular product from
+http://www.datageekery.com/[Data Geekery] which generates Java code from your
+database, and lets you build type safe SQL queries through its fluent API. Both the
+commercial and open source editions can be used with Spring Boot.
+
+
+
+=== Code Generation
+In oder to use jOOQ type-safe queries, you need to generate Java classes from your
+database schema. You can follow the instructions in the
+http://www.jooq.org/doc/3.6/manual-single-page/#jooq-in-7-steps-step3[jOOQ user manual].
+If you are using the `jooq-codegen-maven` plugin (and you also use the
+`spring-boot-starter-parent` "`parent POM`") you can safely omit the plugin's ``
+tag. You can also use Spring Boot defined version variables (e.g. `h2.version`) to
+declare the plugin's database dependency. Here's an example:
+
+[source,xml,indent=0]
+----
+
+ org.jooq
+ jooq-codegen-maven
+
+ ...
+
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+
+
+ org.h2.Driver
+ jdbc:h2:~/yourdatabase
+
+
+ ...
+
+
+
+----
+
+
+
+=== Using DSLContext
+The fluent API offered by jOOQ is initiated via the `org.jooq.DSLContext` interface.
+Spring Boot will auto-configure a `DSLContext` as a Spring Bean and connect it to your
+application `DataSource`. To use the `DSLContext` you can just `@Autowire` it:
+
+[source,java,indent=0]
+----
+ @Component
+ public class JooqExample implements CommandLineRunner {
+
+ private final DSLContext create;
+
+ @Autowired
+ public JooqExample(DSLContext dlsContext) {
+ this.create = dlsContext;
+ }
+
+ }
+----
+
+TIP: The jOOQ manual tends to use a variable named `create` to hold the `DSLContext`,
+we've done the same for this example.
+
+You can then use the `DSLContext` to construct your queries:
+
+[source,java,indent=0]
+----
+ public List authorsBornAfter1980() {
+ return this.create.selectFrom(AUTHOR)
+ .where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
+ .fetch(AUTHOR.DATE_OF_BIRTH);
+ }
+----
+
+
+
+=== Customizing jOOQ
+You can customize the SQL dialect used by jOOQ by setting `spring.jooq.sql-dialect` in
+your `application.properties`. For example, to specify Postgres you would add:
+
+[source,properties,indent=0]
+----
+ spring.jooq.sql-dialect=Postgres
+----
+
+More advanced customizations can be achieved by defining your own `@Bean` definitions
+which will be used when the jOOQ `Configuration` is created. You can define beans for
+the following jOOQ Types:
+
+* `ConnectionProvider`
+* `TransactionProvider`
+* `RecordMapperProvider`
+* `RecordListenerProvider`
+* `ExecuteListenerProvider`
+* `VisitListenerProvider`
+
+You can also create your own `org.jooq.Configuration` `@Bean` if you want to take
+complete control of the jOOQ configuration.
+
+
+
[[boot-features-nosql]]
== Working with NoSQL technologies
Spring Data provides additional projects that help you access a variety of NoSQL
diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml
index fa65e4bc82..fb39902274 100644
--- a/spring-boot-samples/pom.xml
+++ b/spring-boot-samples/pom.xml
@@ -33,6 +33,7 @@
spring-boot-sample-cachespring-boot-sample-data-elasticsearchspring-boot-sample-data-gemfire
+ spring-boot-sample-data-jooqspring-boot-sample-data-jpaspring-boot-sample-data-mongodbspring-boot-sample-data-redis
diff --git a/spring-boot-samples/spring-boot-sample-jooq/README.adoc b/spring-boot-samples/spring-boot-sample-jooq/README.adoc
new file mode 100644
index 0000000000..17e6be3742
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/README.adoc
@@ -0,0 +1,9 @@
+== jOOQ Sample
+
+To rerun the code generator:
+
+[indent=0]
+----
+ $ rm -fr gensrc
+ $ mvn clean generate-sources -Pgenerate
+----
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Keys.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Keys.java
new file mode 100644
index 0000000000..6a6fde5c32
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Keys.java
@@ -0,0 +1,81 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain;
+
+
+import javax.annotation.Generated;
+
+import org.jooq.ForeignKey;
+import org.jooq.UniqueKey;
+import org.jooq.impl.AbstractKeys;
+
+import sample.jooq.domain.tables.Author;
+import sample.jooq.domain.tables.Book;
+import sample.jooq.domain.tables.BookStore;
+import sample.jooq.domain.tables.BookToBookStore;
+import sample.jooq.domain.tables.Language;
+import sample.jooq.domain.tables.records.AuthorRecord;
+import sample.jooq.domain.tables.records.BookRecord;
+import sample.jooq.domain.tables.records.BookStoreRecord;
+import sample.jooq.domain.tables.records.BookToBookStoreRecord;
+import sample.jooq.domain.tables.records.LanguageRecord;
+
+
+/**
+ * A class modelling foreign key relationships between tables of the PUBLIC
+ * schema
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Keys {
+
+ // -------------------------------------------------------------------------
+ // IDENTITY definitions
+ // -------------------------------------------------------------------------
+
+
+ // -------------------------------------------------------------------------
+ // UNIQUE and PRIMARY KEY definitions
+ // -------------------------------------------------------------------------
+
+ public static final UniqueKey CONSTRAINT_C = UniqueKeys0.CONSTRAINT_C;
+ public static final UniqueKey CONSTRAINT_7 = UniqueKeys0.CONSTRAINT_7;
+ public static final UniqueKey CONSTRAINT_1 = UniqueKeys0.CONSTRAINT_1;
+ public static final UniqueKey CONSTRAINT_F = UniqueKeys0.CONSTRAINT_F;
+ public static final UniqueKey CONSTRAINT_2 = UniqueKeys0.CONSTRAINT_2;
+
+ // -------------------------------------------------------------------------
+ // FOREIGN KEY definitions
+ // -------------------------------------------------------------------------
+
+ public static final ForeignKey FK_BOOK_AUTHOR = ForeignKeys0.FK_BOOK_AUTHOR;
+ public static final ForeignKey FK_BOOK_LANGUAGE = ForeignKeys0.FK_BOOK_LANGUAGE;
+ public static final ForeignKey FK_B2BS_BOOK_STORE = ForeignKeys0.FK_B2BS_BOOK_STORE;
+ public static final ForeignKey FK_B2BS_BOOK = ForeignKeys0.FK_B2BS_BOOK;
+
+ // -------------------------------------------------------------------------
+ // [#1459] distribute members to avoid static initialisers > 64kb
+ // -------------------------------------------------------------------------
+
+ private static class UniqueKeys0 extends AbstractKeys {
+ public static final UniqueKey CONSTRAINT_C = createUniqueKey(Language.LANGUAGE, Language.LANGUAGE.ID);
+ public static final UniqueKey CONSTRAINT_7 = createUniqueKey(Author.AUTHOR, Author.AUTHOR.ID);
+ public static final UniqueKey CONSTRAINT_1 = createUniqueKey(Book.BOOK, Book.BOOK.ID);
+ public static final UniqueKey CONSTRAINT_F = createUniqueKey(BookStore.BOOK_STORE, BookStore.BOOK_STORE.NAME);
+ public static final UniqueKey CONSTRAINT_2 = createUniqueKey(BookToBookStore.BOOK_TO_BOOK_STORE, BookToBookStore.BOOK_TO_BOOK_STORE.NAME, BookToBookStore.BOOK_TO_BOOK_STORE.BOOK_ID);
+ }
+
+ private static class ForeignKeys0 extends AbstractKeys {
+ public static final ForeignKey FK_BOOK_AUTHOR = createForeignKey(sample.jooq.domain.Keys.CONSTRAINT_7, Book.BOOK, Book.BOOK.AUTHOR_ID);
+ public static final ForeignKey FK_BOOK_LANGUAGE = createForeignKey(sample.jooq.domain.Keys.CONSTRAINT_C, Book.BOOK, Book.BOOK.LANGUAGE_ID);
+ public static final ForeignKey FK_B2BS_BOOK_STORE = createForeignKey(sample.jooq.domain.Keys.CONSTRAINT_F, BookToBookStore.BOOK_TO_BOOK_STORE, BookToBookStore.BOOK_TO_BOOK_STORE.NAME);
+ public static final ForeignKey FK_B2BS_BOOK = createForeignKey(sample.jooq.domain.Keys.CONSTRAINT_1, BookToBookStore.BOOK_TO_BOOK_STORE, BookToBookStore.BOOK_TO_BOOK_STORE.BOOK_ID);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Public.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Public.java
new file mode 100644
index 0000000000..68dd8675b6
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Public.java
@@ -0,0 +1,65 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import org.jooq.Table;
+import org.jooq.impl.SchemaImpl;
+
+import sample.jooq.domain.tables.Author;
+import sample.jooq.domain.tables.Book;
+import sample.jooq.domain.tables.BookStore;
+import sample.jooq.domain.tables.BookToBookStore;
+import sample.jooq.domain.tables.Language;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Public extends SchemaImpl {
+
+ private static final long serialVersionUID = 1051839433;
+
+ /**
+ * The reference instance of PUBLIC
+ */
+ public static final Public PUBLIC = new Public();
+
+ /**
+ * No further instances allowed
+ */
+ private Public() {
+ super("PUBLIC");
+ }
+
+ @Override
+ public final List
> getTables() {
+ List result = new ArrayList();
+ result.addAll(getTables0());
+ return result;
+ }
+
+ private final List
> getTables0() {
+ return Arrays.
>asList(
+ Language.LANGUAGE,
+ Author.AUTHOR,
+ Book.BOOK,
+ BookStore.BOOK_STORE,
+ BookToBookStore.BOOK_TO_BOOK_STORE);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Tables.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Tables.java
new file mode 100644
index 0000000000..e9888a06cd
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Tables.java
@@ -0,0 +1,53 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain;
+
+
+import javax.annotation.Generated;
+
+import sample.jooq.domain.tables.Author;
+import sample.jooq.domain.tables.Book;
+import sample.jooq.domain.tables.BookStore;
+import sample.jooq.domain.tables.BookToBookStore;
+import sample.jooq.domain.tables.Language;
+
+
+/**
+ * Convenience access to all tables in PUBLIC
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Tables {
+
+ /**
+ * The table PUBLIC.LANGUAGE
+ */
+ public static final Language LANGUAGE = sample.jooq.domain.tables.Language.LANGUAGE;
+
+ /**
+ * The table PUBLIC.AUTHOR
+ */
+ public static final Author AUTHOR = sample.jooq.domain.tables.Author.AUTHOR;
+
+ /**
+ * The table PUBLIC.BOOK
+ */
+ public static final Book BOOK = sample.jooq.domain.tables.Book.BOOK;
+
+ /**
+ * The table PUBLIC.BOOK_STORE
+ */
+ public static final BookStore BOOK_STORE = sample.jooq.domain.tables.BookStore.BOOK_STORE;
+
+ /**
+ * The table PUBLIC.BOOK_TO_BOOK_STORE
+ */
+ public static final BookToBookStore BOOK_TO_BOOK_STORE = sample.jooq.domain.tables.BookToBookStore.BOOK_TO_BOOK_STORE;
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Author.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Author.java
new file mode 100644
index 0000000000..5bef981db9
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Author.java
@@ -0,0 +1,134 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables;
+
+
+import java.sql.Date;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.UniqueKey;
+import org.jooq.impl.TableImpl;
+
+import sample.jooq.domain.Keys;
+import sample.jooq.domain.Public;
+import sample.jooq.domain.tables.records.AuthorRecord;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Author extends TableImpl {
+
+ private static final long serialVersionUID = -1989221607;
+
+ /**
+ * The reference instance of PUBLIC.AUTHOR
+ */
+ public static final Author AUTHOR = new Author();
+
+ /**
+ * The class holding records for this type
+ */
+ @Override
+ public Class getRecordType() {
+ return AuthorRecord.class;
+ }
+
+ /**
+ * The column PUBLIC.AUTHOR.ID.
+ */
+ public final TableField ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.AUTHOR.FIRST_NAME.
+ */
+ public final TableField FIRST_NAME = createField("FIRST_NAME", org.jooq.impl.SQLDataType.VARCHAR.length(50), this, "");
+
+ /**
+ * The column PUBLIC.AUTHOR.LAST_NAME.
+ */
+ public final TableField LAST_NAME = createField("LAST_NAME", org.jooq.impl.SQLDataType.VARCHAR.length(50).nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.AUTHOR.DATE_OF_BIRTH.
+ */
+ public final TableField DATE_OF_BIRTH = createField("DATE_OF_BIRTH", org.jooq.impl.SQLDataType.DATE, this, "");
+
+ /**
+ * The column PUBLIC.AUTHOR.YEAR_OF_BIRTH.
+ */
+ public final TableField YEAR_OF_BIRTH = createField("YEAR_OF_BIRTH", org.jooq.impl.SQLDataType.INTEGER, this, "");
+
+ /**
+ * The column PUBLIC.AUTHOR.DISTINGUISHED.
+ */
+ public final TableField DISTINGUISHED = createField("DISTINGUISHED", org.jooq.impl.SQLDataType.TINYINT, this, "");
+
+ /**
+ * Create a PUBLIC.AUTHOR table reference
+ */
+ public Author() {
+ this("AUTHOR", null);
+ }
+
+ /**
+ * Create an aliased PUBLIC.AUTHOR table reference
+ */
+ public Author(String alias) {
+ this(alias, AUTHOR);
+ }
+
+ private Author(String alias, Table aliased) {
+ this(alias, aliased, null);
+ }
+
+ private Author(String alias, Table aliased, Field>[] parameters) {
+ super(alias, Public.PUBLIC, aliased, parameters, "");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public UniqueKey getPrimaryKey() {
+ return Keys.CONSTRAINT_7;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List> getKeys() {
+ return Arrays.>asList(Keys.CONSTRAINT_7);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Author as(String alias) {
+ return new Author(alias, this);
+ }
+
+ /**
+ * Rename this table
+ */
+ public Author rename(String name) {
+ return new Author(name, null);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Book.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Book.java
new file mode 100644
index 0000000000..a4fb3fad4c
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Book.java
@@ -0,0 +1,137 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables;
+
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.ForeignKey;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.UniqueKey;
+import org.jooq.impl.TableImpl;
+
+import sample.jooq.domain.Keys;
+import sample.jooq.domain.Public;
+import sample.jooq.domain.tables.records.BookRecord;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Book extends TableImpl {
+
+ private static final long serialVersionUID = 1858247563;
+
+ /**
+ * The reference instance of PUBLIC.BOOK
+ */
+ public static final Book BOOK = new Book();
+
+ /**
+ * The class holding records for this type
+ */
+ @Override
+ public Class getRecordType() {
+ return BookRecord.class;
+ }
+
+ /**
+ * The column PUBLIC.BOOK.ID.
+ */
+ public final TableField ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.BOOK.AUTHOR_ID.
+ */
+ public final TableField AUTHOR_ID = createField("AUTHOR_ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.BOOK.TITLE.
+ */
+ public final TableField TITLE = createField("TITLE", org.jooq.impl.SQLDataType.VARCHAR.length(400).nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.BOOK.PUBLISHED_IN.
+ */
+ public final TableField PUBLISHED_IN = createField("PUBLISHED_IN", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.BOOK.LANGUAGE_ID.
+ */
+ public final TableField LANGUAGE_ID = createField("LANGUAGE_ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * Create a PUBLIC.BOOK table reference
+ */
+ public Book() {
+ this("BOOK", null);
+ }
+
+ /**
+ * Create an aliased PUBLIC.BOOK table reference
+ */
+ public Book(String alias) {
+ this(alias, BOOK);
+ }
+
+ private Book(String alias, Table aliased) {
+ this(alias, aliased, null);
+ }
+
+ private Book(String alias, Table aliased, Field>[] parameters) {
+ super(alias, Public.PUBLIC, aliased, parameters, "");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public UniqueKey getPrimaryKey() {
+ return Keys.CONSTRAINT_1;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List> getKeys() {
+ return Arrays.>asList(Keys.CONSTRAINT_1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List> getReferences() {
+ return Arrays.>asList(Keys.FK_BOOK_AUTHOR, Keys.FK_BOOK_LANGUAGE);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Book as(String alias) {
+ return new Book(alias, this);
+ }
+
+ /**
+ * Rename this table
+ */
+ public Book rename(String name) {
+ return new Book(name, null);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookStore.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookStore.java
new file mode 100644
index 0000000000..988cdbeba5
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookStore.java
@@ -0,0 +1,100 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables;
+
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.UniqueKey;
+import org.jooq.impl.TableImpl;
+
+import sample.jooq.domain.Keys;
+import sample.jooq.domain.Public;
+import sample.jooq.domain.tables.records.BookStoreRecord;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class BookStore extends TableImpl {
+
+ private static final long serialVersionUID = 1437758195;
+
+ /**
+ * The reference instance of PUBLIC.BOOK_STORE
+ */
+ public static final BookStore BOOK_STORE = new BookStore();
+
+ /**
+ * The class holding records for this type
+ */
+ @Override
+ public Class getRecordType() {
+ return BookStoreRecord.class;
+ }
+
+ /**
+ * The column PUBLIC.BOOK_STORE.NAME.
+ */
+ public final TableField NAME = createField("NAME", org.jooq.impl.SQLDataType.VARCHAR.length(400).nullable(false), this, "");
+
+ /**
+ * Create a PUBLIC.BOOK_STORE table reference
+ */
+ public BookStore() {
+ this("BOOK_STORE", null);
+ }
+
+ /**
+ * Create an aliased PUBLIC.BOOK_STORE table reference
+ */
+ public BookStore(String alias) {
+ this(alias, BOOK_STORE);
+ }
+
+ private BookStore(String alias, Table aliased) {
+ this(alias, aliased, null);
+ }
+
+ private BookStore(String alias, Table aliased, Field>[] parameters) {
+ super(alias, Public.PUBLIC, aliased, parameters, "");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List> getKeys() {
+ return Arrays.>asList(Keys.CONSTRAINT_F);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookStore as(String alias) {
+ return new BookStore(alias, this);
+ }
+
+ /**
+ * Rename this table
+ */
+ public BookStore rename(String name) {
+ return new BookStore(name, null);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookToBookStore.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookToBookStore.java
new file mode 100644
index 0000000000..71f2e2cac8
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookToBookStore.java
@@ -0,0 +1,127 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables;
+
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.ForeignKey;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.UniqueKey;
+import org.jooq.impl.TableImpl;
+
+import sample.jooq.domain.Keys;
+import sample.jooq.domain.Public;
+import sample.jooq.domain.tables.records.BookToBookStoreRecord;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class BookToBookStore extends TableImpl {
+
+ private static final long serialVersionUID = -557222072;
+
+ /**
+ * The reference instance of PUBLIC.BOOK_TO_BOOK_STORE
+ */
+ public static final BookToBookStore BOOK_TO_BOOK_STORE = new BookToBookStore();
+
+ /**
+ * The class holding records for this type
+ */
+ @Override
+ public Class getRecordType() {
+ return BookToBookStoreRecord.class;
+ }
+
+ /**
+ * The column PUBLIC.BOOK_TO_BOOK_STORE.NAME.
+ */
+ public final TableField NAME = createField("NAME", org.jooq.impl.SQLDataType.VARCHAR.length(400).nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.BOOK_TO_BOOK_STORE.BOOK_ID.
+ */
+ public final TableField BOOK_ID = createField("BOOK_ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.BOOK_TO_BOOK_STORE.STOCK.
+ */
+ public final TableField STOCK = createField("STOCK", org.jooq.impl.SQLDataType.INTEGER, this, "");
+
+ /**
+ * Create a PUBLIC.BOOK_TO_BOOK_STORE table reference
+ */
+ public BookToBookStore() {
+ this("BOOK_TO_BOOK_STORE", null);
+ }
+
+ /**
+ * Create an aliased PUBLIC.BOOK_TO_BOOK_STORE table reference
+ */
+ public BookToBookStore(String alias) {
+ this(alias, BOOK_TO_BOOK_STORE);
+ }
+
+ private BookToBookStore(String alias, Table aliased) {
+ this(alias, aliased, null);
+ }
+
+ private BookToBookStore(String alias, Table aliased, Field>[] parameters) {
+ super(alias, Public.PUBLIC, aliased, parameters, "");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public UniqueKey getPrimaryKey() {
+ return Keys.CONSTRAINT_2;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List> getKeys() {
+ return Arrays.>asList(Keys.CONSTRAINT_2);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List> getReferences() {
+ return Arrays.>asList(Keys.FK_B2BS_BOOK_STORE, Keys.FK_B2BS_BOOK);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookToBookStore as(String alias) {
+ return new BookToBookStore(alias, this);
+ }
+
+ /**
+ * Rename this table
+ */
+ public BookToBookStore rename(String name) {
+ return new BookToBookStore(name, null);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Language.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Language.java
new file mode 100644
index 0000000000..e34784d859
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Language.java
@@ -0,0 +1,118 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables;
+
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.UniqueKey;
+import org.jooq.impl.TableImpl;
+
+import sample.jooq.domain.Keys;
+import sample.jooq.domain.Public;
+import sample.jooq.domain.tables.records.LanguageRecord;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class Language extends TableImpl {
+
+ private static final long serialVersionUID = -192479483;
+
+ /**
+ * The reference instance of PUBLIC.LANGUAGE
+ */
+ public static final Language LANGUAGE = new Language();
+
+ /**
+ * The class holding records for this type
+ */
+ @Override
+ public Class getRecordType() {
+ return LanguageRecord.class;
+ }
+
+ /**
+ * The column PUBLIC.LANGUAGE.ID.
+ */
+ public final TableField ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.LANGUAGE.CD.
+ */
+ public final TableField CD = createField("CD", org.jooq.impl.SQLDataType.CHAR.length(2).nullable(false), this, "");
+
+ /**
+ * The column PUBLIC.LANGUAGE.DESCRIPTION.
+ */
+ public final TableField DESCRIPTION = createField("DESCRIPTION", org.jooq.impl.SQLDataType.VARCHAR.length(50), this, "");
+
+ /**
+ * Create a PUBLIC.LANGUAGE table reference
+ */
+ public Language() {
+ this("LANGUAGE", null);
+ }
+
+ /**
+ * Create an aliased PUBLIC.LANGUAGE table reference
+ */
+ public Language(String alias) {
+ this(alias, LANGUAGE);
+ }
+
+ private Language(String alias, Table aliased) {
+ this(alias, aliased, null);
+ }
+
+ private Language(String alias, Table aliased, Field>[] parameters) {
+ super(alias, Public.PUBLIC, aliased, parameters, "");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public UniqueKey getPrimaryKey() {
+ return Keys.CONSTRAINT_C;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List> getKeys() {
+ return Arrays.>asList(Keys.CONSTRAINT_C);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Language as(String alias) {
+ return new Language(alias, this);
+ }
+
+ /**
+ * Rename this table
+ */
+ public Language rename(String name) {
+ return new Language(name, null);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/AuthorRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/AuthorRecord.java
new file mode 100644
index 0000000000..b6190a7286
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/AuthorRecord.java
@@ -0,0 +1,339 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables.records;
+
+
+import java.sql.Date;
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.Record1;
+import org.jooq.Record6;
+import org.jooq.Row6;
+import org.jooq.impl.UpdatableRecordImpl;
+
+import sample.jooq.domain.tables.Author;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class AuthorRecord extends UpdatableRecordImpl implements Record6 {
+
+ private static final long serialVersionUID = -983051550;
+
+ /**
+ * Setter for PUBLIC.AUTHOR.ID.
+ */
+ public void setId(Integer value) {
+ setValue(0, value);
+ }
+
+ /**
+ * Getter for PUBLIC.AUTHOR.ID.
+ */
+ public Integer getId() {
+ return (Integer) getValue(0);
+ }
+
+ /**
+ * Setter for PUBLIC.AUTHOR.FIRST_NAME.
+ */
+ public void setFirstName(String value) {
+ setValue(1, value);
+ }
+
+ /**
+ * Getter for PUBLIC.AUTHOR.FIRST_NAME.
+ */
+ public String getFirstName() {
+ return (String) getValue(1);
+ }
+
+ /**
+ * Setter for PUBLIC.AUTHOR.LAST_NAME.
+ */
+ public void setLastName(String value) {
+ setValue(2, value);
+ }
+
+ /**
+ * Getter for PUBLIC.AUTHOR.LAST_NAME.
+ */
+ public String getLastName() {
+ return (String) getValue(2);
+ }
+
+ /**
+ * Setter for PUBLIC.AUTHOR.DATE_OF_BIRTH.
+ */
+ public void setDateOfBirth(Date value) {
+ setValue(3, value);
+ }
+
+ /**
+ * Getter for PUBLIC.AUTHOR.DATE_OF_BIRTH.
+ */
+ public Date getDateOfBirth() {
+ return (Date) getValue(3);
+ }
+
+ /**
+ * Setter for PUBLIC.AUTHOR.YEAR_OF_BIRTH.
+ */
+ public void setYearOfBirth(Integer value) {
+ setValue(4, value);
+ }
+
+ /**
+ * Getter for PUBLIC.AUTHOR.YEAR_OF_BIRTH.
+ */
+ public Integer getYearOfBirth() {
+ return (Integer) getValue(4);
+ }
+
+ /**
+ * Setter for PUBLIC.AUTHOR.DISTINGUISHED.
+ */
+ public void setDistinguished(Byte value) {
+ setValue(5, value);
+ }
+
+ /**
+ * Getter for PUBLIC.AUTHOR.DISTINGUISHED.
+ */
+ public Byte getDistinguished() {
+ return (Byte) getValue(5);
+ }
+
+ // -------------------------------------------------------------------------
+ // Primary key information
+ // -------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Record1 key() {
+ return (Record1) super.key();
+ }
+
+ // -------------------------------------------------------------------------
+ // Record6 type implementation
+ // -------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row6 fieldsRow() {
+ return (Row6) super.fieldsRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row6 valuesRow() {
+ return (Row6) super.valuesRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field1() {
+ return Author.AUTHOR.ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field2() {
+ return Author.AUTHOR.FIRST_NAME;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field3() {
+ return Author.AUTHOR.LAST_NAME;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field4() {
+ return Author.AUTHOR.DATE_OF_BIRTH;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field5() {
+ return Author.AUTHOR.YEAR_OF_BIRTH;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field6() {
+ return Author.AUTHOR.DISTINGUISHED;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer value1() {
+ return getId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String value2() {
+ return getFirstName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String value3() {
+ return getLastName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Date value4() {
+ return getDateOfBirth();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer value5() {
+ return getYearOfBirth();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Byte value6() {
+ return getDistinguished();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuthorRecord value1(Integer value) {
+ setId(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuthorRecord value2(String value) {
+ setFirstName(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuthorRecord value3(String value) {
+ setLastName(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuthorRecord value4(Date value) {
+ setDateOfBirth(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuthorRecord value5(Integer value) {
+ setYearOfBirth(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuthorRecord value6(Byte value) {
+ setDistinguished(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuthorRecord values(Integer value1, String value2, String value3, Date value4, Integer value5, Byte value6) {
+ value1(value1);
+ value2(value2);
+ value3(value3);
+ value4(value4);
+ value5(value5);
+ value6(value6);
+ return this;
+ }
+
+ // -------------------------------------------------------------------------
+ // Constructors
+ // -------------------------------------------------------------------------
+
+ /**
+ * Create a detached AuthorRecord
+ */
+ public AuthorRecord() {
+ super(Author.AUTHOR);
+ }
+
+ /**
+ * Create a detached, initialised AuthorRecord
+ */
+ public AuthorRecord(Integer id, String firstName, String lastName, Date dateOfBirth, Integer yearOfBirth, Byte distinguished) {
+ super(Author.AUTHOR);
+
+ setValue(0, id);
+ setValue(1, firstName);
+ setValue(2, lastName);
+ setValue(3, dateOfBirth);
+ setValue(4, yearOfBirth);
+ setValue(5, distinguished);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookRecord.java
new file mode 100644
index 0000000000..f55c6509df
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookRecord.java
@@ -0,0 +1,296 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables.records;
+
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.Record1;
+import org.jooq.Record5;
+import org.jooq.Row5;
+import org.jooq.impl.UpdatableRecordImpl;
+
+import sample.jooq.domain.tables.Book;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class BookRecord extends UpdatableRecordImpl implements Record5 {
+
+ private static final long serialVersionUID = 220424682;
+
+ /**
+ * Setter for PUBLIC.BOOK.ID.
+ */
+ public void setId(Integer value) {
+ setValue(0, value);
+ }
+
+ /**
+ * Getter for PUBLIC.BOOK.ID.
+ */
+ public Integer getId() {
+ return (Integer) getValue(0);
+ }
+
+ /**
+ * Setter for PUBLIC.BOOK.AUTHOR_ID.
+ */
+ public void setAuthorId(Integer value) {
+ setValue(1, value);
+ }
+
+ /**
+ * Getter for PUBLIC.BOOK.AUTHOR_ID.
+ */
+ public Integer getAuthorId() {
+ return (Integer) getValue(1);
+ }
+
+ /**
+ * Setter for PUBLIC.BOOK.TITLE.
+ */
+ public void setTitle(String value) {
+ setValue(2, value);
+ }
+
+ /**
+ * Getter for PUBLIC.BOOK.TITLE.
+ */
+ public String getTitle() {
+ return (String) getValue(2);
+ }
+
+ /**
+ * Setter for PUBLIC.BOOK.PUBLISHED_IN.
+ */
+ public void setPublishedIn(Integer value) {
+ setValue(3, value);
+ }
+
+ /**
+ * Getter for PUBLIC.BOOK.PUBLISHED_IN.
+ */
+ public Integer getPublishedIn() {
+ return (Integer) getValue(3);
+ }
+
+ /**
+ * Setter for PUBLIC.BOOK.LANGUAGE_ID.
+ */
+ public void setLanguageId(Integer value) {
+ setValue(4, value);
+ }
+
+ /**
+ * Getter for PUBLIC.BOOK.LANGUAGE_ID.
+ */
+ public Integer getLanguageId() {
+ return (Integer) getValue(4);
+ }
+
+ // -------------------------------------------------------------------------
+ // Primary key information
+ // -------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Record1 key() {
+ return (Record1) super.key();
+ }
+
+ // -------------------------------------------------------------------------
+ // Record5 type implementation
+ // -------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row5 fieldsRow() {
+ return (Row5) super.fieldsRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row5 valuesRow() {
+ return (Row5) super.valuesRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field1() {
+ return Book.BOOK.ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field2() {
+ return Book.BOOK.AUTHOR_ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field3() {
+ return Book.BOOK.TITLE;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field4() {
+ return Book.BOOK.PUBLISHED_IN;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field5() {
+ return Book.BOOK.LANGUAGE_ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer value1() {
+ return getId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer value2() {
+ return getAuthorId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String value3() {
+ return getTitle();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer value4() {
+ return getPublishedIn();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer value5() {
+ return getLanguageId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookRecord value1(Integer value) {
+ setId(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookRecord value2(Integer value) {
+ setAuthorId(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookRecord value3(String value) {
+ setTitle(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookRecord value4(Integer value) {
+ setPublishedIn(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookRecord value5(Integer value) {
+ setLanguageId(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookRecord values(Integer value1, Integer value2, String value3, Integer value4, Integer value5) {
+ value1(value1);
+ value2(value2);
+ value3(value3);
+ value4(value4);
+ value5(value5);
+ return this;
+ }
+
+ // -------------------------------------------------------------------------
+ // Constructors
+ // -------------------------------------------------------------------------
+
+ /**
+ * Create a detached BookRecord
+ */
+ public BookRecord() {
+ super(Book.BOOK);
+ }
+
+ /**
+ * Create a detached, initialised BookRecord
+ */
+ public BookRecord(Integer id, Integer authorId, String title, Integer publishedIn, Integer languageId) {
+ super(Book.BOOK);
+
+ setValue(0, id);
+ setValue(1, authorId);
+ setValue(2, title);
+ setValue(3, publishedIn);
+ setValue(4, languageId);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookStoreRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookStoreRecord.java
new file mode 100644
index 0000000000..c119cc5527
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookStoreRecord.java
@@ -0,0 +1,119 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables.records;
+
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.Record1;
+import org.jooq.Row1;
+import org.jooq.impl.TableRecordImpl;
+
+import sample.jooq.domain.tables.BookStore;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class BookStoreRecord extends TableRecordImpl implements Record1 {
+
+ private static final long serialVersionUID = -1969224219;
+
+ /**
+ * Setter for PUBLIC.BOOK_STORE.NAME.
+ */
+ public void setName(String value) {
+ setValue(0, value);
+ }
+
+ /**
+ * Getter for PUBLIC.BOOK_STORE.NAME.
+ */
+ public String getName() {
+ return (String) getValue(0);
+ }
+
+ // -------------------------------------------------------------------------
+ // Record1 type implementation
+ // -------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row1 fieldsRow() {
+ return (Row1) super.fieldsRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row1 valuesRow() {
+ return (Row1) super.valuesRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field1() {
+ return BookStore.BOOK_STORE.NAME;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String value1() {
+ return getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookStoreRecord value1(String value) {
+ setName(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookStoreRecord values(String value1) {
+ value1(value1);
+ return this;
+ }
+
+ // -------------------------------------------------------------------------
+ // Constructors
+ // -------------------------------------------------------------------------
+
+ /**
+ * Create a detached BookStoreRecord
+ */
+ public BookStoreRecord() {
+ super(BookStore.BOOK_STORE);
+ }
+
+ /**
+ * Create a detached, initialised BookStoreRecord
+ */
+ public BookStoreRecord(String name) {
+ super(BookStore.BOOK_STORE);
+
+ setValue(0, name);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookToBookStoreRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookToBookStoreRecord.java
new file mode 100644
index 0000000000..2da6f1f9e8
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookToBookStoreRecord.java
@@ -0,0 +1,214 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables.records;
+
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.Record2;
+import org.jooq.Record3;
+import org.jooq.Row3;
+import org.jooq.impl.UpdatableRecordImpl;
+
+import sample.jooq.domain.tables.BookToBookStore;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class BookToBookStoreRecord extends UpdatableRecordImpl implements Record3 {
+
+ private static final long serialVersionUID = 1124329527;
+
+ /**
+ * Setter for PUBLIC.BOOK_TO_BOOK_STORE.NAME.
+ */
+ public void setName(String value) {
+ setValue(0, value);
+ }
+
+ /**
+ * Getter for PUBLIC.BOOK_TO_BOOK_STORE.NAME.
+ */
+ public String getName() {
+ return (String) getValue(0);
+ }
+
+ /**
+ * Setter for PUBLIC.BOOK_TO_BOOK_STORE.BOOK_ID.
+ */
+ public void setBookId(Integer value) {
+ setValue(1, value);
+ }
+
+ /**
+ * Getter for PUBLIC.BOOK_TO_BOOK_STORE.BOOK_ID.
+ */
+ public Integer getBookId() {
+ return (Integer) getValue(1);
+ }
+
+ /**
+ * Setter for PUBLIC.BOOK_TO_BOOK_STORE.STOCK.
+ */
+ public void setStock(Integer value) {
+ setValue(2, value);
+ }
+
+ /**
+ * Getter for PUBLIC.BOOK_TO_BOOK_STORE.STOCK.
+ */
+ public Integer getStock() {
+ return (Integer) getValue(2);
+ }
+
+ // -------------------------------------------------------------------------
+ // Primary key information
+ // -------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Record2 key() {
+ return (Record2) super.key();
+ }
+
+ // -------------------------------------------------------------------------
+ // Record3 type implementation
+ // -------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row3 fieldsRow() {
+ return (Row3) super.fieldsRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row3 valuesRow() {
+ return (Row3) super.valuesRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field1() {
+ return BookToBookStore.BOOK_TO_BOOK_STORE.NAME;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field2() {
+ return BookToBookStore.BOOK_TO_BOOK_STORE.BOOK_ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field3() {
+ return BookToBookStore.BOOK_TO_BOOK_STORE.STOCK;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String value1() {
+ return getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer value2() {
+ return getBookId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer value3() {
+ return getStock();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookToBookStoreRecord value1(String value) {
+ setName(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookToBookStoreRecord value2(Integer value) {
+ setBookId(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookToBookStoreRecord value3(Integer value) {
+ setStock(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BookToBookStoreRecord values(String value1, Integer value2, Integer value3) {
+ value1(value1);
+ value2(value2);
+ value3(value3);
+ return this;
+ }
+
+ // -------------------------------------------------------------------------
+ // Constructors
+ // -------------------------------------------------------------------------
+
+ /**
+ * Create a detached BookToBookStoreRecord
+ */
+ public BookToBookStoreRecord() {
+ super(BookToBookStore.BOOK_TO_BOOK_STORE);
+ }
+
+ /**
+ * Create a detached, initialised BookToBookStoreRecord
+ */
+ public BookToBookStoreRecord(String name, Integer bookId, Integer stock) {
+ super(BookToBookStore.BOOK_TO_BOOK_STORE);
+
+ setValue(0, name);
+ setValue(1, bookId);
+ setValue(2, stock);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/LanguageRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/LanguageRecord.java
new file mode 100644
index 0000000000..bb23679ce7
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/LanguageRecord.java
@@ -0,0 +1,214 @@
+/**
+ * This class is generated by jOOQ
+ */
+package sample.jooq.domain.tables.records;
+
+
+import javax.annotation.Generated;
+
+import org.jooq.Field;
+import org.jooq.Record1;
+import org.jooq.Record3;
+import org.jooq.Row3;
+import org.jooq.impl.UpdatableRecordImpl;
+
+import sample.jooq.domain.tables.Language;
+
+
+/**
+ * This class is generated by jOOQ.
+ */
+@Generated(
+ value = {
+ "http://www.jooq.org",
+ "jOOQ version:3.6.2"
+ },
+ comments = "This class is generated by jOOQ"
+)
+@SuppressWarnings({ "all", "unchecked", "rawtypes" })
+public class LanguageRecord extends UpdatableRecordImpl implements Record3 {
+
+ private static final long serialVersionUID = -1003202585;
+
+ /**
+ * Setter for PUBLIC.LANGUAGE.ID.
+ */
+ public void setId(Integer value) {
+ setValue(0, value);
+ }
+
+ /**
+ * Getter for PUBLIC.LANGUAGE.ID.
+ */
+ public Integer getId() {
+ return (Integer) getValue(0);
+ }
+
+ /**
+ * Setter for PUBLIC.LANGUAGE.CD.
+ */
+ public void setCd(String value) {
+ setValue(1, value);
+ }
+
+ /**
+ * Getter for PUBLIC.LANGUAGE.CD.
+ */
+ public String getCd() {
+ return (String) getValue(1);
+ }
+
+ /**
+ * Setter for PUBLIC.LANGUAGE.DESCRIPTION.
+ */
+ public void setDescription(String value) {
+ setValue(2, value);
+ }
+
+ /**
+ * Getter for PUBLIC.LANGUAGE.DESCRIPTION.
+ */
+ public String getDescription() {
+ return (String) getValue(2);
+ }
+
+ // -------------------------------------------------------------------------
+ // Primary key information
+ // -------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Record1 key() {
+ return (Record1) super.key();
+ }
+
+ // -------------------------------------------------------------------------
+ // Record3 type implementation
+ // -------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row3 fieldsRow() {
+ return (Row3) super.fieldsRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Row3 valuesRow() {
+ return (Row3) super.valuesRow();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field1() {
+ return Language.LANGUAGE.ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field2() {
+ return Language.LANGUAGE.CD;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Field field3() {
+ return Language.LANGUAGE.DESCRIPTION;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Integer value1() {
+ return getId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String value2() {
+ return getCd();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String value3() {
+ return getDescription();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public LanguageRecord value1(Integer value) {
+ setId(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public LanguageRecord value2(String value) {
+ setCd(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public LanguageRecord value3(String value) {
+ setDescription(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public LanguageRecord values(Integer value1, String value2, String value3) {
+ value1(value1);
+ value2(value2);
+ value3(value3);
+ return this;
+ }
+
+ // -------------------------------------------------------------------------
+ // Constructors
+ // -------------------------------------------------------------------------
+
+ /**
+ * Create a detached LanguageRecord
+ */
+ public LanguageRecord() {
+ super(Language.LANGUAGE);
+ }
+
+ /**
+ * Create a detached, initialised LanguageRecord
+ */
+ public LanguageRecord(Integer id, String cd, String description) {
+ super(Language.LANGUAGE);
+
+ setValue(0, id);
+ setValue(1, cd);
+ setValue(2, description);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/pom.xml b/spring-boot-samples/spring-boot-sample-jooq/pom.xml
new file mode 100644
index 0000000000..dfa84d7cb2
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/pom.xml
@@ -0,0 +1,171 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-samples
+ 1.3.0.BUILD-SNAPSHOT
+
+ spring-boot-sample-jooq
+ Spring Boot jOOQ Sample
+ Spring Boot jOOQ Sample
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jooq
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ generate-sources
+
+ add-source
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.jooq
+
+ jooq-codegen-maven
+
+
+ [3.6.2,)
+
+
+ generate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ generate
+
+
+
+ org.codehaus.mojo
+ sql-maven-plugin
+ 1.5
+
+
+ generate-sources
+
+ execute
+
+
+
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+
+ org.h2.Driver
+ jdbc:h2:~/springbootjooq
+
+ ${basedir}/src/main/resources/reset.sql
+ ${basedir}/src/main/resources/schema.sql
+
+
+
+
+ org.jooq
+ jooq-codegen-maven
+
+
+
+ generate
+
+
+
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+
+
+ org.h2.Driver
+ jdbc:h2:~/springbootjooq
+
+
+ org.jooq.util.DefaultGenerator
+
+ org.jooq.util.h2.H2Database
+ .*
+
+ PUBLIC
+
+
+ sample.jooq.domain
+ ${basedir}/gensrc/main/java
+
+
+
+
+
+
+
+
+
diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/JooqExamples.java b/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/JooqExamples.java
new file mode 100644
index 0000000000..46fdb74af6
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/JooqExamples.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package sample.jooq;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import org.jooq.DSLContext;
+import org.jooq.Query;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Component;
+
+import static sample.jooq.domain.tables.Author.AUTHOR;
+import static sample.jooq.domain.tables.Book.BOOK;
+
+@Component
+public class JooqExamples implements CommandLineRunner {
+
+ private final DSLContext dsl;
+
+ private final JdbcTemplate jdbc;
+
+ @Autowired
+ public JooqExamples(DSLContext dsl, JdbcTemplate jdbc) {
+ this.dsl = dsl;
+ this.jdbc = jdbc;
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+ jooqFetch();
+ jooqSql();
+ }
+
+ private void jooqFetch() {
+ Result results = this.dsl.select().from(AUTHOR).fetch();
+ for (Record result : results) {
+ Integer id = result.getValue(AUTHOR.ID);
+ String firstName = result.getValue(AUTHOR.FIRST_NAME);
+ String lastName = result.getValue(AUTHOR.LAST_NAME);
+ System.out.println("jOOQ Fetch " + id + " " + firstName + " " + lastName);
+ }
+ }
+
+ private void jooqSql() {
+ Query query = this.dsl.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
+ .from(BOOK).join(AUTHOR).on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
+ .where(BOOK.PUBLISHED_IN.equal(2015));
+ Object[] bind = query.getBindValues().toArray(new Object[] {});
+ List list = this.jdbc.query(query.getSQL(), bind,
+ new RowMapper() {
+ @Override
+ public String mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return rs.getString(1) + " : " + rs.getString(2) + " "
+ + rs.getString(3);
+ }
+ });
+ System.out.println("jOOQ SQL " + list);
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/SampleJooqApplication.java b/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/SampleJooqApplication.java
new file mode 100644
index 0000000000..aa0dcac00e
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/SampleJooqApplication.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package sample.jooq;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SampleJooqApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleJooqApplication.class, args);
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/data.sql b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/data.sql
new file mode 100644
index 0000000000..8e8994e9d0
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/data.sql
@@ -0,0 +1,12 @@
+INSERT INTO language VALUES (1, 'EN', 'English');
+
+INSERT INTO author VALUES (1, 'Greg', 'Turnquest', '1804-09-17', 1804, 1);
+INSERT INTO author VALUES (2, 'Craig', 'Walls', '1804-09-18', 1804, 1);
+
+INSERT INTO book VALUES (1, 1, 'Learning Spring Boot', 2015, 1);
+INSERT INTO book VALUES (2, 2, 'Spring Boot in Action', 2015, 1);
+
+INSERT INTO book_store VALUES ('Barnes & Noble');
+
+INSERT INTO book_to_book_store VALUES ('Barnes & Noble', 1, 10);
+INSERT INTO book_to_book_store VALUES ('Barnes & Noble', 2, 3);
diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/reset.sql b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/reset.sql
new file mode 100644
index 0000000000..fc9a4f21da
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/reset.sql
@@ -0,0 +1 @@
+DROP ALL OBJECTS;
\ No newline at end of file
diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/schema.sql b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/schema.sql
new file mode 100644
index 0000000000..0cc7aee7e4
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/schema.sql
@@ -0,0 +1,39 @@
+CREATE TABLE language (
+ id NUMBER(7) NOT NULL PRIMARY KEY,
+ cd CHAR(2) NOT NULL,
+ description VARCHAR2(50)
+);
+
+CREATE TABLE author (
+ id NUMBER(7) NOT NULL PRIMARY KEY,
+ first_name VARCHAR2(50),
+ last_name VARCHAR2(50) NOT NULL,
+ date_of_birth DATE,
+ year_of_birth NUMBER(7),
+ distinguished NUMBER(1)
+);
+
+CREATE TABLE book (
+ id NUMBER(7) NOT NULL PRIMARY KEY,
+ author_id NUMBER(7) NOT NULL,
+ title VARCHAR2(400) NOT NULL,
+ published_in NUMBER(7) NOT NULL,
+ language_id NUMBER(7) NOT NULL,
+
+ CONSTRAINT fk_book_author FOREIGN KEY (author_id) REFERENCES author(id),
+ CONSTRAINT fk_book_language FOREIGN KEY (language_id) REFERENCES language(id)
+);
+
+CREATE TABLE book_store (
+ name VARCHAR2(400) NOT NULL UNIQUE
+);
+
+CREATE TABLE book_to_book_store (
+ name VARCHAR2(400) NOT NULL,
+ book_id INTEGER NOT NULL,
+ stock INTEGER,
+
+ PRIMARY KEY(name, book_id),
+ CONSTRAINT fk_b2bs_book_store FOREIGN KEY (name) REFERENCES book_store (name) ON DELETE CASCADE,
+ CONSTRAINT fk_b2bs_book FOREIGN KEY (book_id) REFERENCES book (id) ON DELETE CASCADE
+);
diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java b/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java
new file mode 100644
index 0000000000..4b3bdaae13
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package sample.jooq;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.springframework.boot.test.OutputCapture;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Integration tests for {@link SampleJooqApplication}.
+ */
+public class SampleJooqApplicationTests {
+
+ private static final String[] NO_ARGS = {};
+
+ @Rule
+ public OutputCapture out = new OutputCapture();
+
+ @Test
+ public void outputResults() throws Exception {
+ SampleJooqApplication.main(NO_ARGS);
+ assertThat(this.out.toString(), containsString("jOOQ Fetch 1 Greg Turnquest"));
+ assertThat(this.out.toString(), containsString("jOOQ Fetch 2 Craig Walls"));
+ assertThat(this.out.toString(), containsString("jOOQ SQL "
+ + "[Learning Spring Boot : Greg Turnquest, "
+ + "Spring Boot in Action : Craig Walls]"));
+ }
+
+}
diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml
index c683196be9..d43c5dc262 100644
--- a/spring-boot-starters/pom.xml
+++ b/spring-boot-starters/pom.xml
@@ -41,6 +41,7 @@
spring-boot-starter-jdbcspring-boot-starter-jerseyspring-boot-starter-jetty
+ spring-boot-starter-jooqspring-boot-starter-jta-atomikosspring-boot-starter-jta-bitronixspring-boot-starter-logging
diff --git a/spring-boot-starters/spring-boot-starter-jooq/pom.xml b/spring-boot-starters/spring-boot-starter-jooq/pom.xml
new file mode 100644
index 0000000000..40cf8f370c
--- /dev/null
+++ b/spring-boot-starters/spring-boot-starter-jooq/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starters
+ 1.3.0.BUILD-SNAPSHOT
+
+ spring-boot-starter-jooq
+ Spring Boot JOOQ Starter
+ Spring Boot JOOQ Starter
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+ org.springframework
+ spring-tx
+
+
+ org.jooq
+ jooq
+
+
+
diff --git a/spring-boot-starters/spring-boot-starter-jooq/src/main/resources/META-INF/spring.provides b/spring-boot-starters/spring-boot-starter-jooq/src/main/resources/META-INF/spring.provides
new file mode 100644
index 0000000000..062b6d60d2
--- /dev/null
+++ b/spring-boot-starters/spring-boot-starter-jooq/src/main/resources/META-INF/spring.provides
@@ -0,0 +1 @@
+provides: jooq
\ No newline at end of file