diff --git a/jdbc/howto/caching/README.adoc b/jdbc/howto/caching/README.adoc
new file mode 100644
index 00000000..00a51857
--- /dev/null
+++ b/jdbc/howto/caching/README.adoc
@@ -0,0 +1,6 @@
+== Spring Data JDBC How To cache.
+
+Spring Data JDBC doesn't include any caching for entities.
+But it is trivially combined with Springs Cache abstraction.
+
+This project demonstrates this.
diff --git a/jdbc/howto/caching/pom.xml b/jdbc/howto/caching/pom.xml
new file mode 100644
index 00000000..e62b8444
--- /dev/null
+++ b/jdbc/howto/caching/pom.xml
@@ -0,0 +1,21 @@
+
+ 4.0.0
+
+ spring-data-jdbc-how-to-caching
+
+
+ org.springframework.data.examples
+ spring-data-jdbc-how-to
+ 2.0.0.BUILD-SNAPSHOT
+ ../pom.xml
+
+
+ Spring Data JDBC - How to do caching
+ Sample project for Spring Data JDBC demonstrating how it can be used with Springs caching
+ abstraction.
+
+ https://projects.spring.io/spring-data-jdbc
+ 2021
+
+
diff --git a/jdbc/howto/caching/src/main/java/example.springdata/jdbc/howto/caching/CachingApplication.java b/jdbc/howto/caching/src/main/java/example.springdata/jdbc/howto/caching/CachingApplication.java
new file mode 100644
index 00000000..7d7c705c
--- /dev/null
+++ b/jdbc/howto/caching/src/main/java/example.springdata/jdbc/howto/caching/CachingApplication.java
@@ -0,0 +1,15 @@
+package example.springdata.jdbc.howto.caching;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cache.annotation.EnableCaching;
+
+@EnableCaching
+@SpringBootApplication
+class CachingApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(CachingApplication.class, args);
+ }
+
+}
diff --git a/jdbc/howto/caching/src/main/java/example.springdata/jdbc/howto/caching/Minion.java b/jdbc/howto/caching/src/main/java/example.springdata/jdbc/howto/caching/Minion.java
new file mode 100644
index 00000000..841756e6
--- /dev/null
+++ b/jdbc/howto/caching/src/main/java/example.springdata/jdbc/howto/caching/Minion.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 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
+ *
+ * https://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.howto.caching;
+
+import org.springframework.data.annotation.Id;
+
+public class Minion {
+ @Id
+ Long id;
+ String name;
+
+ Minion(String name) {
+ this.name = name;
+ }
+
+ public Long getId(){
+ return id;
+ }
+}
diff --git a/jdbc/howto/caching/src/main/java/example.springdata/jdbc/howto/caching/MinionRepository.java b/jdbc/howto/caching/src/main/java/example.springdata/jdbc/howto/caching/MinionRepository.java
new file mode 100644
index 00000000..9b73b0cb
--- /dev/null
+++ b/jdbc/howto/caching/src/main/java/example.springdata/jdbc/howto/caching/MinionRepository.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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
+ *
+ * https://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.howto.caching;
+
+import java.util.Optional;
+
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.data.repository.CrudRepository;
+
+interface MinionRepository extends CrudRepository {
+
+ @Override
+ @CacheEvict(value="minions",beforeInvocation = false,key = "#result.id")
+ S save(S s);
+
+ @Override
+ @Cacheable("minions")
+ Optional findById(Long aLong);
+}
diff --git a/jdbc/howto/caching/src/main/resources/application.properties b/jdbc/howto/caching/src/main/resources/application.properties
new file mode 100644
index 00000000..813de42f
--- /dev/null
+++ b/jdbc/howto/caching/src/main/resources/application.properties
@@ -0,0 +1 @@
+logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG
\ No newline at end of file
diff --git a/jdbc/howto/caching/src/main/resources/schema.sql b/jdbc/howto/caching/src/main/resources/schema.sql
new file mode 100644
index 00000000..5e75d228
--- /dev/null
+++ b/jdbc/howto/caching/src/main/resources/schema.sql
@@ -0,0 +1,5 @@
+CREATE TABLE MINION
+(
+ ID IDENTITY PRIMARY KEY,
+ NAME VARCHAR(255),
+);
diff --git a/jdbc/howto/caching/src/test/java/example/springdata/jdbc/howto/caching/CachingApplicationTests.java b/jdbc/howto/caching/src/test/java/example/springdata/jdbc/howto/caching/CachingApplicationTests.java
new file mode 100644
index 00000000..4043391f
--- /dev/null
+++ b/jdbc/howto/caching/src/test/java/example/springdata/jdbc/howto/caching/CachingApplicationTests.java
@@ -0,0 +1,39 @@
+package example.springdata.jdbc.howto.caching;
+
+import java.util.Optional;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class CachingApplicationTests {
+
+ private Long bobsId;
+ @Autowired MinionRepository minions;
+
+ @BeforeEach
+ void setup() {
+
+ Minion bob = minions.save(new Minion("Bob"));
+ bobsId = bob.id;
+ }
+
+ @Test
+ void saveloadMultipleTimes() {
+
+ Optional bob = null;
+ for (int i = 0; i < 10; i++) {
+ bob = minions.findById(bobsId);
+ }
+
+ minions.save(bob.get());
+
+ for (int i = 0; i < 10; i++) {
+ bob = minions.findById(bobsId);
+ }
+
+ }
+
+}
diff --git a/jdbc/howto/pom.xml b/jdbc/howto/pom.xml
index 53dd42ec..044ae5e1 100644
--- a/jdbc/howto/pom.xml
+++ b/jdbc/howto/pom.xml
@@ -21,6 +21,7 @@
bidirectionalexternal
bidirectionalinternal
+ caching
idgeneration