diff --git a/jdbc/jooq/README.adoc b/jdbc/jooq/README.adoc
new file mode 100644
index 00000000..c1f0169b
--- /dev/null
+++ b/jdbc/jooq/README.adoc
@@ -0,0 +1,18 @@
+== Spring Data JDBC with jOOQ
+
+The `JooqMethods` class demonstrates how to access a database with jOOQ in combination with Spring Data JDBC.
+The domain model is based on the basic JDBC example for comparison.
+Another interesting aspect of this code could be the jOOQ configuration in the `pom.xml` file.
+
+To execute the tests, execute:
+[indent=0]
+----
+ $ mvn test
+----
+
+The code generator is automatically run when executing the tests.
+If you want to rerun the code generator manually, just execute the following command:
+[indent=0]
+----
+ $ mvn clean generate-sources
+----
diff --git a/jdbc/jooq/pom.xml b/jdbc/jooq/pom.xml
new file mode 100644
index 00000000..13a3a3c4
--- /dev/null
+++ b/jdbc/jooq/pom.xml
@@ -0,0 +1,75 @@
+
+ 4.0.0
+
+ spring-data-jdbc-jooq
+
+
+ org.springframework.data.examples
+ spring-data-jdbc-examples
+ 2.0.0.BUILD-SNAPSHOT
+ ../pom.xml
+
+
+ Spring Data JDBC - Usage with jOOQ
+ Sample project demonstrating Spring Data JDBC features
+
+
+ 3.11.0
+ 2.0.3.RELEASE
+
+
+
+
+ org.jooq
+ jooq
+ ${jooq.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-jooq
+ ${spring-boot-starter-jooq.version}
+
+
+ org.jooq
+ jooq-meta-extensions
+ ${jooq.version}
+
+
+
+
+
+
+ org.jooq
+ jooq-codegen-maven
+ ${jooq.version}
+
+
+
+
+ generate
+
+
+
+
+
+
+
+ org.jooq.meta.extensions.ddl.DDLDatabase
+
+
+ scripts
+ ${basedir}/src/main/resources/schema.sql
+
+
+
+
+ example.springdata.jdbc.basics.simpleentity.domain
+ ${basedir}/gensrc/main/java
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/AgeGroup.java b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/AgeGroup.java
new file mode 100644
index 00000000..f7dbc09b
--- /dev/null
+++ b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/AgeGroup.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2017-2018 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 example.springdata.jdbc.jooq;
+
+/**
+ * Age group for which a LegoSet is intended.
+ *
+ * @author Jens Schauder
+ */
+public enum AgeGroup {
+
+ _0to3,
+ _3to8,
+ _8to12,
+ _12andOlder
+}
diff --git a/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/Category.java b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/Category.java
new file mode 100644
index 00000000..52d59473
--- /dev/null
+++ b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/Category.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017-2018 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 example.springdata.jdbc.jooq;
+
+import lombok.Data;
+import org.springframework.data.annotation.Id;
+
+/**
+ * Coarse classification for LegoSets, like "Car", "Plane", "Building" and so on.
+ *
+ * @author Jens Schauder
+ * @author Florian Lüdiger
+ */
+@Data
+public class Category {
+
+ private final @Id Long id;
+ private String name, description;
+ private AgeGroup ageGroup;
+
+ public Category(Long id, String name, String description, AgeGroup ageGroup) {
+ this.id = id;
+ this.name = name;
+ this.description = description;
+ this.ageGroup = ageGroup;
+ }
+}
diff --git a/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/CategoryConfiguration.java b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/CategoryConfiguration.java
new file mode 100644
index 00000000..14e8abac
--- /dev/null
+++ b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/CategoryConfiguration.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017-2018 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 example.springdata.jdbc.jooq;
+
+import org.jooq.impl.DataSourceConnectionProvider;
+import org.jooq.impl.DefaultConfiguration;
+import org.jooq.impl.DefaultDSLContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
+import org.springframework.data.jdbc.repository.config.JdbcConfiguration;
+import org.springframework.data.relational.core.mapping.event.RelationalEvent;
+import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
+
+import javax.sql.DataSource;
+
+/**
+ * Contains infrastructure necessary for creating repositories and two listeners.
+ *
+ * Not that a listener may change an entity without any problem.
+ *
+ * @author Jens Schauder
+ * @author Mark Paluch
+ * @author Florian Lüdiger
+ */
+@Configuration
+@EnableJdbcRepositories
+@Import(JdbcConfiguration.class)
+public class CategoryConfiguration {
+
+ @Autowired
+ private DataSource dataSource;
+
+ @Bean
+ public ApplicationListener> loggingListener() {
+
+ return (ApplicationListener) event -> {
+ if (event instanceof RelationalEvent) {
+ System.out.println("Received an event: " + event);
+ }
+ };
+ }
+
+ @Bean
+ public DataSourceConnectionProvider connectionProvider() {
+ return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
+ }
+
+ @Bean
+ DefaultDSLContext dsl() {
+ return new DefaultDSLContext(configuration());
+ }
+
+ public DefaultConfiguration configuration() {
+ DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
+ jooqConfiguration.set(connectionProvider());
+ return jooqConfiguration;
+ }
+}
diff --git a/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/CategoryRepository.java b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/CategoryRepository.java
new file mode 100644
index 00000000..958fff7e
--- /dev/null
+++ b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/CategoryRepository.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2017-2018 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 example.springdata.jdbc.jooq;
+
+import org.springframework.data.repository.CrudRepository;
+
+/**
+ * Repository for Categories.
+ *
+ * @author Jens Schauder
+ */
+interface CategoryRepository extends CrudRepository, JooqRepository {
+}
diff --git a/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/JooqRepository.java b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/JooqRepository.java
new file mode 100644
index 00000000..2ab8a90f
--- /dev/null
+++ b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/JooqRepository.java
@@ -0,0 +1,7 @@
+package example.springdata.jdbc.jooq;
+
+import java.util.List;
+
+public interface JooqRepository {
+ List getCategoriesWithAgeGroup(AgeGroup ageGroup);
+}
diff --git a/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/JooqRepositoryImpl.java b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/JooqRepositoryImpl.java
new file mode 100644
index 00000000..a9e960ff
--- /dev/null
+++ b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/JooqRepositoryImpl.java
@@ -0,0 +1,29 @@
+package example.springdata.jdbc.jooq;
+
+import org.jooq.DSLContext;
+
+import java.util.List;
+
+import static example.springdata.jdbc.basics.simpleentity.domain.tables.Category.CATEGORY;
+
+/**
+ * Implementations for custom repository access using jOOQ.
+ *
+ * @author Florian Lüdiger
+ */
+public class JooqRepositoryImpl implements JooqRepository {
+
+ private final DSLContext dslContext;
+
+ public JooqRepositoryImpl(DSLContext dslContext) {
+ this.dslContext = dslContext;
+ }
+
+ public List getCategoriesWithAgeGroup(AgeGroup ageGroup) {
+ return this.dslContext
+ .select()
+ .from(CATEGORY)
+ .where(CATEGORY.AGE_GROUP.equal(ageGroup.name()))
+ .fetchInto(Category.class);
+ }
+}
diff --git a/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/Output.java b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/Output.java
new file mode 100644
index 00000000..5be4e15f
--- /dev/null
+++ b/jdbc/jooq/src/main/java/example/springdata/jdbc/jooq/Output.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017-2018 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 example.springdata.jdbc.jooq;
+
+import lombok.experimental.UtilityClass;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Trivial class to print domain objects to the console in a somewhat readable format.
+ *
+ * @author Jens Schauder
+ */
+@UtilityClass
+public class Output {
+
+ private final Logger LOG = LoggerFactory.getLogger(Output.class);
+
+ public static void list(Iterable> categories, String title) {
+
+ StringBuilder message = new StringBuilder(String.format("==== %s ====\n", title));
+
+ categories.forEach(category -> message.append(category.toString().replace(", ", ",\n\t")));
+
+ LOG.info(message.toString());
+ }
+}
diff --git a/jdbc/jooq/src/main/resources/application.properties b/jdbc/jooq/src/main/resources/application.properties
new file mode 100644
index 00000000..2804353d
--- /dev/null
+++ b/jdbc/jooq/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+logging.level.org.springframework.data=INFO
+logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG
\ No newline at end of file
diff --git a/jdbc/jooq/src/main/resources/schema.sql b/jdbc/jooq/src/main/resources/schema.sql
new file mode 100644
index 00000000..600c536a
--- /dev/null
+++ b/jdbc/jooq/src/main/resources/schema.sql
@@ -0,0 +1,6 @@
+CREATE TABLE IF NOT EXISTS category (
+ id INTEGER IDENTITY PRIMARY KEY,
+ name VARCHAR(100),
+ description VARCHAR(2000),
+ age_group VARCHAR(20)
+);
diff --git a/jdbc/jooq/src/test/java/example/springdata/jdbc/jooq/SimpleEntityTests.java b/jdbc/jooq/src/test/java/example/springdata/jdbc/jooq/SimpleEntityTests.java
new file mode 100644
index 00000000..2943f55c
--- /dev/null
+++ b/jdbc/jooq/src/test/java/example/springdata/jdbc/jooq/SimpleEntityTests.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2017-2018 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 example.springdata.jdbc.jooq;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Demonstrates simple CRUD operations with a simple entity without any references.
+ *
+ * @author Jens Schauder
+ * @author Florian Lüdiger
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = CategoryConfiguration.class)
+@AutoConfigureJdbc
+@ComponentScan
+public class SimpleEntityTests {
+
+ @Autowired
+ CategoryRepository repository;
+
+ @Test
+ public void exerciseRepositoryForSimpleEntity() {
+
+ // create some categories
+ Category cars = new Category(null,"Cars", "Anything that has approximately 4 wheels", AgeGroup._3to8);
+
+ Category buildings = new Category(null,"Buildings", null, AgeGroup._12andOlder);
+
+ // save categories
+ repository.saveAll(asList(cars, buildings));
+ Output.list(repository.findAll(), "`Cars` and `Buildings` got saved");
+
+ assertThat(cars.getId()).isNotNull();
+ assertThat(buildings.getId()).isNotNull();
+
+ // update one
+ buildings.setDescription("Famous and impressive buildings incl. the 'bike shed'.");
+ repository.save(buildings);
+ Output.list(repository.findAll(), "`Buildings` has a description");
+
+ List categoryList = repository.getCategoriesWithAgeGroup(AgeGroup._3to8);
+ assertThat(categoryList.size()).isEqualTo(1);
+ assertThat(categoryList.get(0).getName()).isEqualTo(cars.getName());
+ assertThat(categoryList.get(0).getDescription()).isEqualTo(cars.getDescription());
+ assertThat(categoryList.get(0).getAgeGroup()).isEqualTo(cars.getAgeGroup());
+ }
+}
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
index 47037038..c973a673 100644
--- a/jdbc/pom.xml
+++ b/jdbc/pom.xml
@@ -20,6 +20,7 @@
basics
mybatis
r2dbc
+ jooq