diff --git a/jpa/envers/README.adoc b/jpa/envers/README.adoc
new file mode 100644
index 00000000..96172a1e
--- /dev/null
+++ b/jpa/envers/README.adoc
@@ -0,0 +1,8 @@
+# Spring Data JPA - Spring Data Envers
+
+This project contains an example of how to use Spring Data JPA in combination with Spring Data Envers.
+
+Envers module is a Hibernate module that works both with Hibernate and JPA. It aims to provide an easy auditing / versioning solution for entity classes.
+
+Spring Data Envers integrates it with Spring Data JPA and makes revision information available directly from JPA based repositories.
+
diff --git a/jpa/envers/pom.xml b/jpa/envers/pom.xml
new file mode 100644
index 00000000..01ae1824
--- /dev/null
+++ b/jpa/envers/pom.xml
@@ -0,0 +1,20 @@
+
+
+
+ spring-data-jpa-examples
+ org.springframework.data.examples
+ 2.0.0.BUILD-gh-603-SNAPSHOT
+
+ 4.0.0
+
+ spring-data-jpa-envers
+
+
+
+ org.springframework.data
+ spring-data-envers
+
+
+
\ No newline at end of file
diff --git a/jpa/envers/src/main/java/example/springdata/jpa/envers/EnversDemoConfiguration.java b/jpa/envers/src/main/java/example/springdata/jpa/envers/EnversDemoConfiguration.java
new file mode 100644
index 00000000..d014da30
--- /dev/null
+++ b/jpa/envers/src/main/java/example/springdata/jpa/envers/EnversDemoConfiguration.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.jpa.envers;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.data.envers.repository.support.EnversRevisionRepositoryFactoryBean;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+/**
+ * Configuration for the Envers Demo.
+ *
+ * Note that a special {@literal repositoryFactoryBeanClass} is configured for Spring
+ * Data Envers support.
+ *
+ * @author Jens Schauder
+ */
+@SpringBootApplication
+@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
+public class EnversDemoConfiguration {}
diff --git a/jpa/envers/src/main/java/example/springdata/jpa/envers/Person.java b/jpa/envers/src/main/java/example/springdata/jpa/envers/Person.java
new file mode 100644
index 00000000..27b372ec
--- /dev/null
+++ b/jpa/envers/src/main/java/example/springdata/jpa/envers/Person.java
@@ -0,0 +1,63 @@
+/*
+ * 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.jpa.envers;
+
+import org.hibernate.envers.Audited;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+/**
+ * An entity with a single non-technical attribute
+ *
+ * @author Jens Schauder
+ */
+@Entity
+@Audited
+public class Person {
+
+ @Id @GeneratedValue Long id;
+
+ String name;
+
+ @Version Long version;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Long getVersion() {
+ return version;
+ }
+
+ public void setVersion(Long version) {
+ this.version = version;
+ }
+}
diff --git a/jpa/envers/src/main/java/example/springdata/jpa/envers/PersonRepository.java b/jpa/envers/src/main/java/example/springdata/jpa/envers/PersonRepository.java
new file mode 100644
index 00000000..0f8b237f
--- /dev/null
+++ b/jpa/envers/src/main/java/example/springdata/jpa/envers/PersonRepository.java
@@ -0,0 +1,27 @@
+/*
+ * 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.jpa.envers;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.history.RevisionRepository;
+
+/**
+ * Repository for persons with revision support
+ *
+ * @author Jens Schauder
+ */
+public interface PersonRepository extends CrudRepository, RevisionRepository {
+}
diff --git a/jpa/envers/src/test/java/example/springdata/jpa/envers/EnversIntegrationTests.java b/jpa/envers/src/test/java/example/springdata/jpa/envers/EnversIntegrationTests.java
new file mode 100644
index 00000000..5ac13268
--- /dev/null
+++ b/jpa/envers/src/test/java/example/springdata/jpa/envers/EnversIntegrationTests.java
@@ -0,0 +1,88 @@
+/*
+ * 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.jpa.envers;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.history.Revision;
+import org.springframework.data.history.RevisionMetadata.RevisionType;
+import org.springframework.data.history.Revisions;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import java.util.Iterator;
+
+/**
+ * Demonstrating the usage of Spring Data Envers
+ *
+ * @author Jens Schauder
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest
+public class EnversIntegrationTests {
+
+ @Autowired PersonRepository repository;
+ @Autowired TransactionTemplate tx;
+
+ @Test
+ void testRepository() {
+
+ Person updated = preparePersonHistory();
+
+ Revisions revisions = repository.findRevisions(updated.id);
+
+
+ Iterator> revisionIterator = revisions.iterator();
+
+ checkNextRevision(revisionIterator, "John", RevisionType.INSERT);
+ checkNextRevision(revisionIterator, "Jonny", RevisionType.UPDATE);
+ checkNextRevision(revisionIterator, null, RevisionType.DELETE);
+ assertThat(revisionIterator.hasNext()).isFalse();
+
+ }
+
+ private void checkNextRevision(Iterator> revisionIterator, String name, RevisionType revisionType) {
+
+ assertThat(revisionIterator.hasNext()).isTrue();
+ Revision revision = revisionIterator.next();
+ assertThat(revision.getEntity().name).isEqualTo(name);
+ assertThat(revision.getMetadata().getRevisionType()).isEqualTo(revisionType);
+ }
+
+ private Person preparePersonHistory() {
+
+ Person john = new Person();
+ john.setName("John");
+
+ //create
+ Person saved = tx.execute(__ -> repository.save(john));
+ assertThat(saved).isNotNull();
+
+ saved.setName("Jonny");
+
+ // update
+ Person updated = tx.execute(__ -> repository.save(saved));
+ assertThat(updated).isNotNull();
+
+ // delete
+ tx.executeWithoutResult(__->repository.delete(updated));
+ return updated;
+ }
+}
diff --git a/jpa/pom.xml b/jpa/pom.xml
index c3124e4b..105943c4 100644
--- a/jpa/pom.xml
+++ b/jpa/pom.xml
@@ -27,6 +27,7 @@
query-by-example
vavr
deferred
+ envers