diff --git a/jpa/multitenant/.gitignore b/jpa/multitenant/.gitignore
new file mode 100644
index 00000000..549e00a2
--- /dev/null
+++ b/jpa/multitenant/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/jpa/multitenant/README.adoc b/jpa/multitenant/README.adoc
new file mode 100644
index 00000000..0c751149
--- /dev/null
+++ b/jpa/multitenant/README.adoc
@@ -0,0 +1,10 @@
+This is the parent project for a couple of examples demonstrating how to integrate Hibernates Multitenant feature with Spring Data JPA.
+
+There are three modules for the three examples.
+
+Each uses a different strategy to separate data by tenant:
+
+1. Partition tables by tenant id.
+2. Use a separate schema per tenant
+3. Use a separate database per tenant.
+
diff --git a/jpa/multitenant/db/pom.xml b/jpa/multitenant/db/pom.xml
new file mode 100644
index 00000000..60c70aa4
--- /dev/null
+++ b/jpa/multitenant/db/pom.xml
@@ -0,0 +1,45 @@
+
+
+ 4.0.0
+
+ hibernate-multitenant-db
+
+
+ org.springframework.data.examples
+ spring-data-jpa-hibernate-multitenant-examples
+ 2.0.0.BUILD-SNAPSHOT
+
+
+ Hibernate Multitenant DB
+
+ Example project demonstrating the integration of Hibernates Multitenant feature with Spring Boot using separate databases.
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/Application.java b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/Application.java
new file mode 100644
index 00000000..e3863b9d
--- /dev/null
+++ b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/Application.java
@@ -0,0 +1,11 @@
+package example.springdata.jpa.hibernatemultitenant.db;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/NoOpConnectionProvider.java b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/NoOpConnectionProvider.java
new file mode 100644
index 00000000..7e3a48b0
--- /dev/null
+++ b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/NoOpConnectionProvider.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2022 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.hibernatemultitenant.db;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import org.hibernate.cfg.AvailableSettings;
+import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NoOpConnectionProvider implements MultiTenantConnectionProvider, HibernatePropertiesCustomizer {
+
+ @Autowired DataSource dataSource;
+
+ @Override
+ public Connection getAnyConnection() throws SQLException {
+ return dataSource.getConnection();
+ }
+
+ @Override
+ public void releaseAnyConnection(Connection connection) throws SQLException {
+ connection.close();
+ }
+
+ @Override
+ public Connection getConnection(String schema) throws SQLException {
+
+ return dataSource.getConnection();
+ }
+
+ @Override
+ public void releaseConnection(String s, Connection connection) throws SQLException {
+ connection.close();
+ }
+
+ @Override
+ public boolean supportsAggressiveRelease() {
+ return false;
+ }
+
+ @Override
+ public boolean isUnwrappableAs(Class> aClass) {
+ return false;
+ }
+
+ @Override
+ public T unwrap(Class aClass) {
+ throw new UnsupportedOperationException("Can't unwrap this.");
+ }
+
+ @Override
+ public void customize(Map hibernateProperties) {
+ hibernateProperties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, this);
+ }
+}
diff --git a/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/Person.java b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/Person.java
new file mode 100644
index 00000000..00215f99
--- /dev/null
+++ b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/Person.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2022 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.hibernatemultitenant.db;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+
+@Entity
+public class Person {
+
+ @Id @GeneratedValue private Long id;
+
+ private String name;
+
+ 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;
+ }
+
+ @Override
+ public String toString() {
+ return "Person{" + "id=" + id + ", name='" + name + '\'' + '}';
+ }
+}
diff --git a/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/Persons.java b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/Persons.java
new file mode 100644
index 00000000..5cface36
--- /dev/null
+++ b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/Persons.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 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.hibernatemultitenant.db;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface Persons extends JpaRepository {
+
+ static Person named(String name) {
+
+ Person person = new Person();
+ person.setName(name);
+ return person;
+ }
+}
diff --git a/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/TenantIdentifierResolver.java b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/TenantIdentifierResolver.java
new file mode 100644
index 00000000..3efb038f
--- /dev/null
+++ b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/TenantIdentifierResolver.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2022 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.hibernatemultitenant.db;
+
+import java.util.Map;
+
+import org.hibernate.cfg.AvailableSettings;
+import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
+import org.springframework.stereotype.Component;
+
+@Component()
+public class TenantIdentifierResolver implements CurrentTenantIdentifierResolver, HibernatePropertiesCustomizer {
+
+ private String currentTenant = "unknown";
+
+ public void setCurrentTenant(String tenant) {
+ currentTenant = tenant;
+ }
+
+ @Override
+ public String resolveCurrentTenantIdentifier() {
+ return currentTenant;
+ }
+
+ @Override
+ public boolean validateExistingCurrentSessions() {
+ return false;
+ }
+
+ @Override
+ public void customize(Map hibernateProperties) {
+ hibernateProperties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, this);
+ }
+}
diff --git a/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/TenantRoutingDatasource.java b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/TenantRoutingDatasource.java
new file mode 100644
index 00000000..ed4438d4
--- /dev/null
+++ b/jpa/multitenant/db/src/main/java/example/springdata/jpa/hibernatemultitenant/db/TenantRoutingDatasource.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022 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.hibernatemultitenant.db;
+
+import java.util.HashMap;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
+import org.springframework.stereotype.Component;
+
+@Component
+public class TenantRoutingDatasource extends AbstractRoutingDataSource {
+
+ @Autowired private TenantIdentifierResolver tenantIdentifierResolver;
+
+ TenantRoutingDatasource() {
+
+ setDefaultTargetDataSource(createEmbeddedDatabase("default"));
+
+ HashMap