The @TenantDiscriminator
annotation is used with the @Multitenant
annotation and the SINGLE-TABLE
mulitenant type to limit what a persistence context can access in single-table mulitenancy.
Annotation Elements
Table 2-67 describes this annotation's elements.
Table 2-67 @TenantDiscriminatorColumn Properties
Annotation Element | Description | Default |
---|---|---|
|
(Optional) The SQL fragment that is used when generating the DDL for the discriminator column. |
The provider-generated SQL to create a column of the specified discriminator type. |
|
(Optional) The name of the context property to apply to the tenant discriminator column. |
|
|
(Optional) The type of object/column to use as a class discriminator. |
|
|
(Optional) The column length for String-based discriminator types. |
The column length for String-based discriminator types. Ignored for other discriminator types. |
|
(Optional) The name of column to be used for the tenant discriminator. |
|
|
Specifies that the tenant discriminator column is part of the primary key of the tables. |
|
|
(Optional) The name of the table that contains the column. |
The name of the table that contains the column. If absent the column is assumed to be in the primary table. This attribute must be specified if the column is on a secondary table. |
Usage
To configure single-table multi-tenancy, you must specify both of the following:
Annotate the entity or mapped superclass to use single-table multi-tenancy, using the @Multitenant
annotation, for example:
@Entity @Table(name=“EMP”) @Multitenant(SINGLE_TABLE)
SINGLE_TABLE
states that the table or tables (Table
and SecondaryTable
) associated with the given entity can be shared among tenants.
Note: The |
Specify the column or columns to be used as the discriminator column, using the @TenantDiscriminatorColumn
annotation, for example:
@Entity @Table(name=“EMP”) @Multitenant(SINGLE_TABLE) @TenantDiscriminatorColumn(name = “TENANT_ID”)
You can specify multiple discriminator columns by using the @TenantDiscriminatorColumns
annotation, for example:
@Entity @Table(name = "EMPLOYEE") @Multitenant(SINGLE_TABLE) @TenantDiscriminatorColumns({ @TenantDiscriminatorColumn(name = "TENANT_ID") @TenantDiscriminatorColumn(name = "TENANT_CODE" contextProperty="eclipselink.tenant-code")})
Using Discriminator Columns
The following characteristics apply to discriminator columns:
On persist, the values of tenant discriminator columns are populated from their associated context properties.
Tenant discriminator columns are application definable. That is, the discriminator column is not tied to a specific column for each shared entity table. You can use TENANT_ID
, T_ID
, etc.
There is no limit on how many tenant discriminator columns an application can define.
Any name can be used for a discriminator column.
Tenant discriminator column(s) must always be used with @Multitenant(SINGLE_TABLE
). You cannot specify the tenant discriminator column(s) only.
Generated schemas can include specified tenant discriminator columns.
Tenant discriminator columns can be mapped or unmapped:
When a tenant discriminator column is mapped, its associated mapping attribute must be marked as read only. With this restriction in place, a tenant discriminator column cannot be part of the entity identifier; it can only be part of the primary key specification on the database.
Both mapped and unmapped properties are used to form the additional criteria when issuing a SELECT
query.
Using Single-Table Multi-Tenancy in an Inheritance Hierarchy
Inheritance strategies are configured by specifying the inheritance type (see @javax.persistence.Inheritance). Single-table multi-tenancy can be used in an inheritance hierarchy, as follows:
Multi-tenant metadata can be applied only at the root level of the inheritance hierarchy when using a SINGLE_TABLE
or JOINED
inheritance strategy.
You can also specify multi-tenant metadata within a TABLE_PER_CLASS
inheritance hierarchy. In this case, every entity has its own table, with all its mapping data (which is not the case with SINGLE_TABLE
or JOINED
strategies). Consequently, in the TABLE_PER_CLASS
strategy, some entities of the hierarchy may be multi-tenant, while others may not be. The other inheritance strategies can only specify multi-tenancy at the root level, because you cannot isolate an entity to a single table to build only its type.
Examples
Table 2-67 shows a number of uses of tenant discriminator columns.
Example 2-110 Using @TenantDiscriminatorColumn Annotation
/** Single tenant discriminator column **/ @Entity @Table(name = "CUSTOMER") @Multitenant @TenantDiscriminatorColumn(name = "TENANT", contextProperty = "multi-tenant.id") public Customer() { ... } /** Multiple tenant discriminator columns using multiple tables **/ @Entity @Table(name = "EMPLOYEE") @SecondaryTable(name = "RESPONSIBILITIES") @Multitenant(SINGLE_TABLE) @TenantDiscriminatorColumns({ @TenantDiscriminatorColumn(name = "TENANT_ID", contextProperty = "employee-tenant.id", length = 20) @TenantDiscriminatorColumn(name = "TENANT_CODE", contextProperty = "employee-tenant.code", discriminatorType = STRING, table = "RESPONSIBILITIES") } ) public Employee() { ... } /** Tenant discriminator column mapped as part of the primary key on the database **/ @Entity @Table(name = "ADDRESS") @Multitenant @TenantDiscriminatorColumn(name = "TENANT", contextProperty = "tenant.id", primaryKey = true) public Address() { ... } /** Mapped tenant discriminator column **/ @Entity @Table(name = "Player") @Multitenant @TenantDiscriminatorColumn(name = "AGE", contextProperty = "tenant.age") public Player() { ... @Basic @Column(name="AGE", insertable="false", updatable="false") public int age; }
Example 2-111 shows the same mappings, using the <tenant-disciminator-column>
XML element in the eclipselink-orm.xml
file.
Example 2-111 Using <tenant-discriminator-column> XML
<!-- Single tenant discriminator column --> <entity class="model.Customer"> <multitenant> <tenant-discriminator-column name="TENANT context-property="multi-tenant.id""/> </multitenant> <table name="CUSTOMER"/> ... </entity>
<!-- Multiple tenant discriminator columns using multiple tables --> <entity class="model.Employee"> <multitenant type="SINGLE_TABLE"> <tenant-discriminator-column name="TENANT_ID" context-property="employee-tenant.id" length="20"/> <tenant-discriminator-column name="TENANT_CODE" context-property="employee-tenant.id" discriminator-type="STRING" table="RESPONSIBILITIES"/> </multitenant> <table name="EMPLOYEE"/> <secondary-table name="RESPONSIBILITIES"/> ... </entity>
<!-- Tenant discriminator column mapped as part of the primary key on the database --> <entity class="model.Address"> <multitenant> <tenant-discriminator-column name="TENANT" context-property="multi-tenant.id" primary-key="true"/> </multitenant> <table name="ADDRESS"/> ... </entity>
<!-- Mapped tenant discriminator column --> <entity class="model.Player"> <multi-tenant> <tenant-discriminator-column name="AGE" context-property="tenant.age"/> </multi-tenant> <table name="PLAYER"/> ... <attributes> <basic name="age" insertable="false" updatable="false"> <column name="AGE"/> </basic> ... </attributes> ... </entity>
See Also
"Using Multitenancy" in Solutions Guide for EclispeLink
Multitenant Examples at http://wiki.eclipse.org/EclipseLink/Examples/JPA/Multitenant