Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "EclipseLink/Examples/JPA/Multitenant"
(→Property configuration and caching scope) |
(→Context property configuration) |
||
Line 134: | Line 134: | ||
The context property configuration can be specified via a persistence unit definition, passed to a create entity manager factory call or set on individual entity managers. | The context property configuration can be specified via a persistence unit definition, passed to a create entity manager factory call or set on individual entity managers. | ||
+ | |||
+ | ==== Persistence unit property definition ==== | ||
<source lang="xml"> | <source lang="xml"> | ||
Line 153: | Line 155: | ||
</source> | </source> | ||
− | + | ==== Entity Manager property definition ==== | |
<source lang="java"> | <source lang="java"> |
Revision as of 15:23, 6 June 2011
EclipseLink (as of 2.3) supports a shared (striped) multitenant table using a tenant discriminator column(s).
EclipseLink supports multitenant entities using its @Multitenant
annotation or <multitenant>
xml element. The @Multitenant
annotation can be used on an @Entity
or @MappedSuperclass
and is used in conjunction with the @TenantDiscriminatorColumn
or <tenant-discriminator-column>
xml element.
The tenant discriminator column defines the tenant identifying database column and there may be 1 or more such columns. These columns can be unmapped or mapped. When mapped, they must be marked as read-only. See the annotation and xml examples to follow.
When a multitenant entity is specified, the tenant discriminator column can default. Its default values are:
- name =
TENANT_ID
(the database column name) - context property =
tenant.id
(the context property used to populate the database column)
Note, through annotations, specifying only a tenant discriminator column itself does not enable a multitenant entity. At a minimum, the @Multitenant
must also be specified. Meaning the minimal configuration is:
@Entity @Table(name="EMP") @Multitenant public Employee() { ... }
The following examples outline other possible configurations using annotations and XML.
Contents
Annotation examples
/** Single discriminator tenant 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; }
XML examples
<!-- 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>
Context property configuration
The context property configuration can be specified via a persistence unit definition, passed to a create entity manager factory call or set on individual entity managers.
Persistence unit property definition
<persistence-unit name="multi-tenant"> ... <properties> <property name="tenant.id" value="707"/> ... </properties> </persistence-unit>
Or alternatively in code as follows:
HashMap properties = new HashMap(); properties.put(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, "707"); EntityManager em = Persistence.createEntityManagerFactory("multi-tenant-pu", properties).createEntityManager();
Entity Manager property definition
EntityManager em = Persistence.createEntityManagerFactory("multi-tenant-pu").createEntityManager(); em.beginTransaction(); em.setProperty("tenant.id", "707"); em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "707"); ...
When a shared persistence unit used, no L2 cache 'striping' is performed, and the eclipselink.multitenant.tenants-share-cache
property must be set indicating that all multitenant entities will have a PROTECTED cache setting.
When using a non-shared persistence unit, the eclipselink.session-name
property must be provided to ensure a unique server session (and cache) is provided for each tenant.