Multitenancy

Multitenancy allows you to deploy an application once and this single application can serve several companies at the same time, where each company has access only to its own data. This is perfect for SaaS (Software as a Service), so you can deploy your application in the cloud and rent it to many customers. Also it's very useful for creating multimunicipality applications for public administration. Even if you're not interested in multicompany applications having several isolated datasets allows you do interesting things, such as having a production and testing databases without effort.
XavaPro supports multitenancy out-of-the-box.

Creating a new organization

To support multitenancy XavaPro uses organizations. You will find the Organizations module in the Admin folder:
multitenancy_en010.png
This module allows you to create a new organization just specifying its name and clicking a button:
multitenancy_en020.png
After clicking on the button "Create new organization", the new organization is ready to be used in the specified URL. The creation process creates a new schema in the database, creates all the application tables and populates the admin tables.
You can go to the company URL (/YourAplication/o/YourCompany) directly or to the application URL (/YourApplication). In the later case the sign in form will ask you for the company with a combo:
multitenancy_en030.png
Each organization has its own users, passwords, roles and rights, of course.

Customization

The syntax for creating and removing schemas depends on your database. Your can specify the syntax for your database with the createSchema and dropSchema (new in v5.7.1) properties en naviox.properties:
# Multitenancy: Only available in XavaPro (http://www.openxava.org/xavapro)
 
# The create schema sentence used for creating a new organization
# This is the default one
createSchema=CREATE SCHEMA ${schema}
# These are by database vendor, you can add yours using the database name
# as suffix (actually the first token of connection.getMetaData().getDatabaseProductName())
createSchema.PostgreSQL=CREATE SCHEMA ${schema}
createSchema.HSQL=CREATE SCHEMA ${schema} AUTHORIZATION DBA
 
# The drop schema sentence used for removing an existing organization
# This is the default one
dropSchema=DROP SCHEMA ${schema} CASCADE
# These are by database vendor, you can add yours using the database name
# as suffix (actually the first token of connection.getMetaData().getDatabaseProductName())
dropSchema.MySQL=DROP SCHEMA ${schema}
If you want to make additional customization, like populating the application tables, creating some initial roles and users, giving a specific modules and folders structure, etc. you can define your own action to create the organization. The original action is defined in Addons/xava/controllers.xml in this way:
<controller name="Organization">
    ...
    <action name="createNewOrganization" mode="detail" takes-long="true"
        class="com.openxava.naviox.actions.CreateNewOrganizationAction"/>
    ...
</controller>
Just define your own class for Organization.createNewOrganization.
You can hide the combo with the list of organizations on sign in adding the next entry to naviox.properties (new v5.6):
showOrganizationOnSignIn=false

JDBC inside organizations (new in v5.6)

Any JPA or Hibernate code (Hibernate since v5.6) from your actions, calculators, entities, etc. goes against the correct schema for the current organization, however that is not the case for JDBC. If you want that your JDBC code goes against the schema of the current organization you have to add the next entry in xava.properties:
connectionRefinerClass=com.openxava.naviox.util.SetCatalogFromPersistenceSchemaConnectionRefiner
This works for databases where catalog and schema are synonymous, such as MySQL.

Shared users between organizations (new in v5.6)

When you use multitenancy with XavaPro each organization has its own group of users totally independent from other organizations. This is OK for many cases, however some applications need to have the same group of users for all the organizations. You can configure your application to work in this way, just check the corresponding option in the configuration module:
multitenancy_en040.png
With "Shared users" activated the users and passwords for all the organizations are those of the root application. You have to create the users in the root application only and when one of these users try to access to an organization he has the option to join:
multitenancy_en050.png
There is a joined role in each organization to define the rights for these users.
When the user sign in with "Shared user" activated, the list of his organizations are shown in order to choose:
multitenancy_en060.png
The user can go to any of his organizations without login again.