Multitenant

Multitenancy is supported out of box, and the default multitenant type is separate schema. A seperate database schema will be created for each instance(system or subsystem).

To support multitenant single table type, a module must provide seed-sql files to add multitenant discriminator columns into tables for the supported database types, and ORM mappings to configure entity multitenancy.

Seed Sql

The discriminator column is instanceId, and its type is big integer.

For example, multitenant seed sql(s) in ExampleHR module for MySql and Oracle databases:

     db/mysql/multitenant/seed.sql
     db/oracle/multitenant/seed.sql
MySql database: alter Employee table:

ALTER TABLE `Employee` add `instanceId` bigint(20) NOT NULL;
ALTER TABLE `Employee` drop KEY `nid`;
ALTER TABLE `Employee` add UNIQUE KEY `nid` (`instanceId`, `nid`);
Oracle database: alter Employee table:

ALTER TABLE Employee add instanceId NUMBER(19,0) NOT NULL;
ALTER TABLE Employee drop CONSTRAINT UK_ExampleHR_EMP_nid;
ALTER TABLE Employee add CONSTRAINT UK_ExampleHR_EMP_nid UNIQUE (instanceId, nid);

ORM mappings

Add orm.xml to configure module entity multitenancy. For example, multitenant orm.xml in ExampleHR module:
     conf/multitenant/orm.xml
Configure Employee entity as single table multitenancy:

	<entity class="Employee" > 
		<multitenant>
			<discriminator-column name="instanceId" type="java.lang.Long" 
				value-mapping-property="instance.id"/>
		</multitenant>	
	</entity>
Multitenant configuration is inheritable by subclasses. See Cmobilecom JPA developer guide for detail.

In META-INF/persistence.xml, add module orm.xml(s) that configure multitenancy. For example,


	<persistence-unit name="system" transaction-type="RESOURCE_LOCAL">
		<mapping-file>System/conf/orm.xml</mapping-file>		
		<mapping-file>System/conf/orm-sys.xml</mapping-file>
		<mapping-file>System/conf/multitenant/orm.xml</mapping-file> 
	</persistence-unit>

System Config

Update the [cmobilecom.home]/conf/system-config.xml (or installation: conf/system-config.xml) to configure single table multitenancy as followings:

	<system id="0001" name="CmobilecomAFExample">

		<moduleNode module="ExampleHR"/>
		<moduleNode module="System"/>
		<persistenceUnit>system</persistenceUnit>
	
		<multitenant>
			<type>SINGLE_TABLE</type>
			<schema>#{db.schema.name}</schema>
			
			<!-- users: single identity (shared by all instances in the same schema) -->
			<sharedEntity>
				<class>com.cmobilecom.af.entity.security.User</class>
				<access>FULL</access>
				<param name="paramName" value="paramValue"/>
			</sharedEntity>
		</multitenant>
	</system>
  
	<subsystem id="0002" name="CmobilecomAFExample">
       
		<moduleNode module="ExampleHR"/>
		<moduleNode module="System"/>
		<persistenceUnit>subsystem_example</persistenceUnit>
	
		<multitenant>
			<type>SINGLE_TABLE</type>
			<schema>#{db.schema.name}</schema>
			
			<!-- users: single identity (shared by system and all instances) -->
			<sharedEntity>
				<class>com.cmobilecom.af.entity.security.User</class>
				<access>CREATE,EDIT,VIEW,OWNER_ACCESS,PRIVACY</access>
				<param name="paramName" value="paramValue"/>
			</sharedEntity>
		</multitenant>	 
	</subsystem>   

Multitenant Type

Multitenant Schema

The schema specifies schema name that supports the following variables: Example 1: single table, use system schema
	#{db.schema.name}
Example 2: single table, use a different schema for all the instances of a subsystem InstanceType
	#{db.schema.name}_#{instanceType.id}
Example 3: separate schemas for different instances of a subsystem InstanceType
	#{db.schema.name}_#{instanceType.id}_#{instance.id}
	#{db.schema.name}_s#{instance.id}
For the system InstanceType, it must be #{db.schema.name}. For a subsystem InstanceType, it can contain #{instanceType.id} and/or #{instance.id}. The default schema for a subsystem instance is #{db.schema.name}_i#{instance.id}.

Single Identity

The singleEntity specifies whether to share users for all the instances of the InstanceType. If false, each tenant(system or subsystem instance) will have its own users. In this case, the persistence unit in META-INF/persistence.xml must include
	<mapping-file>System/conf/multitenant/orm-user.xml</mapping-file>
For the system InstanceType, if the User entity is configured as single table multitenancy(for example, the User table is shared with instances), the installation seed/seed.xml must include the following
	<seedSql>System/db/@DBMS_TYPE@/multitenant/user.sql</seedSql>