Skip to content

Commit be1d75e

Browse files
committed
HHH-19559 document schema-based multitenancy
1 parent 6cdb3e9 commit be1d75e

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

documentation/src/main/asciidoc/introduction/Advanced.adoc

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -268,27 +268,56 @@ var entityManager =
268268

269269
However, since we often don't have this level of control over creation of the session, it's more common to supply an implementation of link:{doc-javadoc-url}org/hibernate/context/spi/CurrentTenantIdentifierResolver.html[`CurrentTenantIdentifierResolver`] to Hibernate.
270270

271-
There are three common ways to implement multi-tenancy:
271+
To make use of multi-tenancy, we'll usually need to set at least one of these configuration properties:
272+
273+
.Multi-tenancy configuration
274+
[%breakable,cols="36,~"]
275+
|===
276+
| Configuration property name | Purpose
277+
278+
| link:{doc-javadoc-url}org/hibernate/cfg/MultiTenancySettings.html#MULTI_TENANT_IDENTIFIER_RESOLVER[`hibernate.tenant_identifier_resolver`] | Specifies the `CurrentTenantIdentifierResolver`
279+
| link:{doc-javadoc-url}org/hibernate/cfg/MultiTenancySettings.html#MULTI_TENANT_SCHEMA_MAPPER[`hibernate.multi_tenant.schema_mapper`] | Specifies the `TenantSchemaMapper` for schema-based multi-tenancy
280+
| link:{doc-javadoc-url}org/hibernate/cfg/MultiTenancySettings.html#MULTI_TENANT_CONNECTION_PROVIDER[`hibernate.multi_tenant_connection_provider`] | Specifies the `MultiTenantConnectionProvider` for database-based multi-tenancy
281+
|===
282+
283+
// Do not configure those properties if you would like the configured `BeanContainer` provide the implementation.
284+
285+
There are three common approaches to multi-tenancy:
272286

273287
1. each tenant has its own database,
274288
2. each tenant has its own schema, or
275289
3. tenants share tables in a single schema, and rows are tagged with the tenant id.
276290

277-
From the point of view of Hibernate, there's little difference between the first two options.
278-
Hibernate will need to obtain a JDBC connection with permissions on the database and schema owned by the current tenant.
291+
[discrete]
292+
==== Database-based multi-tenancy
279293

280-
Therefore, we must implement a link:{doc-javadoc-url}org/hibernate/engine/jdbc/connections/spi/MultiTenantConnectionProvider.html[`MultiTenantConnectionProvider`] which takes on this responsibility:
294+
The first option is to give each tenant its own database.
295+
That is, we'll use a separate source of JDBC connections for each tenant.
296+
297+
The interface link:{doc-javadoc-url}org/hibernate/engine/jdbc/connections/spi/MultiTenantConnectionProvider.html[`MultiTenantConnectionProvider`] is responsible for obtaining an appropriate `Connection` for a given tenant.
298+
Typically, we'll provide a custom implementation of this interface:
281299

282300
- from time to time, Hibernate will ask for a connection, passing the id of the current tenant, and then we must create an appropriate connection or obtain one from a pool, and return it to Hibernate, and
283301
- later, Hibernate will release the connection and ask us to destroy it or return it to the appropriate pool.
284302

285303
[TIP]
286304
====
287305
Check out link:{doc-javadoc-url}org/hibernate/engine/jdbc/connections/spi/DataSourceBasedMultiTenantConnectionProviderImpl.html[`DataSourceBasedMultiTenantConnectionProviderImpl`] for inspiration.
306+
If your source of JDBC connections is a set of JNDI-bound ``DataSource``s, you might even be able to use this implementation directly.
288307
====
289308

309+
[discrete]
310+
==== Schema-based multi-tenancy
311+
312+
The second option is to keep all the data for different tenants in the same database, giving each tenant a different named database schema with its own set of tables.
313+
314+
In this case we must supply a link:{doc-javadoc-url}org/hibernate/context/spi/TenantSchemaMapper.html[`TenantSchemaMapper`] which is responsible for mapping from tenant ids to schema names.
315+
316+
[discrete]
317+
==== Discriminator-based multi-tenancy
318+
290319
The third option is quite different.
291-
In this case we don't need a `MultiTenantConnectionProvider`, but we will need a dedicated column holding the tenant id mapped by each of our entities.
320+
In this case we store data from all tenants in the same tables, but each table has a dedicated column holding the tenant id mapped by each of our entities.
292321

293322
[source,java]
294323
----
@@ -309,20 +338,6 @@ Within a given session, our data is automatically filtered so that only rows tag
309338
Native SQL queries are _not_ automatically filtered by tenant id; you'll have to do that part yourself.
310339
====
311340

312-
To make use of multi-tenancy, we'll usually need to set at least one of these configuration properties:
313-
314-
.Multi-tenancy configuration
315-
[%breakable,cols="36,~"]
316-
|===
317-
| Configuration property name | Purpose
318-
319-
| link:{doc-javadoc-url}org/hibernate/cfg/MultiTenancySettings.html#MULTI_TENANT_IDENTIFIER_RESOLVER[`hibernate.tenant_identifier_resolver`] | Specifies the `CurrentTenantIdentifierResolver`
320-
| link:{doc-javadoc-url}org/hibernate/cfg/MultiTenancySettings.html#MULTI_TENANT_CONNECTION_PROVIDER[`hibernate.multi_tenant_connection_provider`] | Specifies the `MultiTenantConnectionProvider`
321-
|===
322-
323-
Do not configure those properties if you would like the configured `BeanContainer` provide the implementation.
324-
A longer discussion of multi-tenancy may be found in the {multitenacy-doc}[User Guide].
325-
326341
[[custom-sql]]
327342
=== Using custom-written SQL
328343

0 commit comments

Comments
 (0)