• No results found

Task 3: Specify Tenant Discriminator Columns

14 Tenant Isolation Using EclipseLink

14.2 Using Single-Table Multi-Tenancy

14.2.1 Main Tasks for Using Single-Table Multi-Tenancy

14.2.1.3 Task 3: Specify Tenant Discriminator Columns

Discriminator columns are used together with an associated application context to indicate which rows in a table an application tenant can access.

Tenant discriminator columns can be specified declaratively using the

@TenantDiscriminatorColumn annotation or in an object-relational (ORM) XML file using the <tenant-discriminator-column> element.

The following characteristics apply to discriminator columns:

Tenant discriminator column(s) must always be used with @Multitenant (or

<multitenant> in the ORM XML file). You cannot specify the tenant discriminator column(s) only.

The tenant discriminator column is assumed to be on the primary table unless another table is explicitly specified.

On persist, the values of tenant discriminator columns are populated from their associated context properties.

When a multi-tenant entity is specified, the tenant discriminator column can default. Its default values are:

Name = TENANT_ID (the database column name)

Context property = eclipselink.tenant.id (the context property used to populate the database column)

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 the number of tenant discriminator columns an application can define.

Any name can be used for a discriminator column.

Generated schemas 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.

Both mapped and unmapped properties are used to form the additional criteria when issuing a SELECT query.

14.2.1.3.1 Use the @TenantDiscriminatorColumn Annotation To use the

@TenantDiscriminatorColumn annotation, include it with @Multitenant annotation on an entity or mapped superclass, and optionally include the name and contextProperty attributes. If you do not specify these attributes, the defaults name = "TENANT-ID" and contextProperty = "eclipselink.tenant-id" are used.

For example:

@Entity

@Multitenant(SINGLE_TABLE)

@TenantDiscriminatorColumn(name = "TENANT", contextProperty = "multitenant.id") public class Employee {

}

To specify multiple tenant discriminator columns, include multiple

@TenantDiscriminatorColumn annotations within the @TenantDiscriminatorColumns

Using Single-Table Multi-Tenancy

Tenant Isolation Using EclipseLink 14-5 annotation, and include the table where the column is located if it is not located on the primary table. For example:

@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")

14.2.1.3.2 Use the <tenant-discriminator-column> Element To use the

<tenant-discriminator-column> element, include the element within a

<multitenant> element and optionally include the name and context-property attributes. If you do not specify these attributes, the defaults name = "TENANT-ID" and contextProperty = "eclipselink.tenant-id" are used.

For example:

<entity class="model.Employee">

<multitenant>

<tenant-discriminator-column name="TENANT"

context-property="multitenant.id"/>

</multitenant>

...

</entity>

To specify multiple columns, include additional <tenant-discriminator-column>

elements, and include the table where the column is located if it is not located on the primary table. For example:

<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>

14.2.1.3.3 Map Tenant Discriminator Columns Tenant discriminator columns can be mapped to a primary key or to another column. The following example maps the tenant discriminator column to the primary key on the table during DDL generation:

@Entity

@Table(name = "ADDRESS")

@Multitenant

Using Single-Table Multi-Tenancy

@TenantDiscriminatorColumn(name = "TENANT", contextProperty = "tenant.id", primaryKey = true)

public Address() { ...

}

The following example uses the ORM XML file to map the tenant discriminator column to a primary key:

<entity class="model.Address">

<multitenant>

<tenant-discriminator-column name="TENANT"

context-property="multitenant.id" primary-key="true"/>

</multitenant>

<table name="ADDRESS"/>

...

</entity>

The following example maps the tenant discriminator column to another column named AGE:

@Entity

@Table(name = "Player")

@Multitenant

@TenantDiscriminatorColumn(name = "AGE", contextProperty = "tenant.age") public Player() {

...

@Basic

@Column(name="AGE", insertable="false", updatable="false") public int age;

}

The following example uses the ORM XML file to map the tenant discriminator column to another column named AGE:

<entity class="model.Player">

<multitenant>

<tenant-discriminator-column name="AGE" context-property="tenant.age"/>

</multitenant>

<table name="PLAYER"/>

...

<attributes>

<basic name="age" insertable="false" updatable="false">

<column name="AGE"/>

14.2.1.3.4 Define Persistence Unit and Entity Mappings Defaults In addition to configuring discriminator columns at the entity and mapped superclass levels, you can also configure them at the persistence-unit-defaults and entity-mappings levels to provide defaults. Defining the metadata at the these levels follows similar JPA metadata defaulting and overriding rules.

Specify default tenant discriminator column metadata at the

persistence-unit-defaults level in the ORM XML file. When defined at this level, the defaults apply to all entities of the persistence unit that have specified a

Using Single-Table Multi-Tenancy

Tenant Isolation Using EclipseLink 14-7 multi-tenant type of SINGLE_TABLE minus those that specify their own tenant

discriminator metadata. For example:

<persistence-unit-metadata>

<persistence-unit-defaults>

<tenant-discriminator-column name="TENANT_ID" context-property="tenant.id"/>

</persistence-unit-defaults>

</persistence-unit-metadata>

You can also specify tenant discriminator column metadata at the entity-mappings level in the ORM XML file. A setting at this level overrides a persistence unit default and applies to all entities with a multi-tenant type of SINGLE_TABLE of the mapping file, minus those that specify their own tenant discriminator metadata. For example:

<entity-mappings>

...

...

<tenant-discriminator-column name="TENANT_ID" context-property="tenant.id"/>

...

</entity-mappings>