Supporting Multi-tenancy 
Applications with Java EE 
Rodrigo Cândido da Silva 
@rcandidosilva 
JavaOne 2014 
CON4959
About Me 
• Brazilian guy ;) 
• Work for Integritas company 
• http://integritastech.com 
• Software Architect 
• Java Platform 
• JUG Leader of GUJavaSC 
• http://gujavasc.org 
• Twitter 
• @rcandidosilva 
• Personal 
• http://rodrigocandido.me
Agenda 
• Cloud Services Model 
• SaaS Market 
• Multi-tenancy 
• Challenges 
• Pros and Cons 
• Strategy Types 
• Java EE + Multi-tenancy 
• Multi-tenancy at Cloud
Cloud Services Model
SaaS Market
Multi-tenancy 
• One application 
instance to multiple 
clients (tenant) 
• Inverse of the multiple 
instances architecture
Multi-instances vs. Multi-tenant
Multi-instances vs. Multi-tenant 
Feature Multi-instances Multi-tenant 
Cost Structure Can support only tiered or 
flat pricing 
Supports usage based pricing 
as well as tiered or flat 
Resources Dedicated resources Shared resources 
Operation and 
Maintenance 
Manage and administer 
as many instances as 
customers 
Manager and administer a 
single instance for a number 
of customers 
Scalable Model Not scalable. As the 
number of customers 
increase the maintenance 
requirements increase 
proporcionally 
Scalable, since a number of 
customers are serviced by 
one instance
Cloud != Multi-tenancy
Challenges 
• Data separation 
• UI and business rules customization 
• Access control by tenant 
• Resource provisioning 
• Integration 
• Application update 
• Failover tolerance
Pros and Cons 
• Pros 
• Low maintenance cost 
• Same source code for all customers 
• High scalability 
• Sharing resources between customers 
• Cons 
• High complexity 
• Separation by tenant-id 
• More failure risks 
• If code breaks -> breaks to all customers 
• Low flexibility available to the customers
Multi-tenancy 
• Adoption levels 
• Level 1 (Customized) 
• [N] applications and [N] databases 
• Level 2 (Configurable) 
• [1] application and [N] databases 
• Level 3 (Scalable) 
• [1] application and [1] database
Level 1 - Customized 
• [N] applications and [N] databases
Level 2 - Configurable 
• [1] application and [N] databases
Level 3 - Scalable 
• [1] application and [1] database
What is the Best Choice? 
• Depends on… 
• Data Customization 
• Addition or removal of columns in the data store 
• Function Customization 
• The functionality executed for a specific business can vary by 
customers 
• Process Customization 
• The business process can vary for each customer 
• Licensing Features 
• The product has multiple licenses which define the functionality 
that is enabled for the customer
Database Strategy 
Separate Databases 
Separate Tables 
Shared Database
Database Strategy 
Feature Separate DBs Separate Tables Shared Database 
Data 
Customization 
Security 
Inter-dependency 
and Performance 
Scalable Model 
Customer On-boarding
Java EE + Multi-tenancy 
• Database 
• JPA + Multi-tenancy 
• UI Customization 
• JSF + Multi-tenancy 
• Java EE 8 with Cloud support
JPA + Multi-tenancy 
• There is no standard at this time 
• EclipseLink 
• Multi-tenancy support using @Multitenant 
• Multitenant strategies 
• @Multitenant(SINGLE_TABLE) – default 
• @Multitenant(TABLE_PER_TENANT) 
• @Multitenant(VPD) 
• Hibernate 
• Supports tenant identifier features 
• MultiTenantConnectionProvider 
• CurrentTenantIdentifierResolver
EclipseLink SINGLE_TABLE 
@Entity 
@Table(name=“EMP”) 
@Multitenant(SINGLE_TABLE) 
@TenantDiscriminatorColumn(name = “TENANT_ID”, 
contextProperty = “tenant-id”) 
public class Employee { 
... 
} 
HashMap properties = new HashMap(); 
properties.put("tenant.id", "707"); 
... 
EntityManager em = Persistence 
.createEntityManagerFactory( 
"multi-tenant”,properties) 
.createEntityManager(); 
<persistence-unit name="multi-tenant"> 
... 
<properties> 
<property name="tenant.id" 
value="707"/> 
... 
</properties> 
</persistence-unit>
EclipseLink TABLE_PER_TENANT 
<entity class="Employee"> 
<multitenant type="TABLE_PER_TENANT"> 
<tenant-table-discriminator type="SCHEMA" context-property=" 
eclipselink.tenant-id"/> 
</multitenant> 
<table name="EMP"> 
... 
</entity> 
@Entity 
@Table(name=“EMP”) 
@Multitenant(TABLE_PER_TENANT) 
@TenantTableDiscriminator(type=SCHEMA, 
contextProperty="eclipselink.tenant-id") 
public class Employee { 
... 
}
EclipseLink VPD 
@Entity 
@Multitenant 
@TenantDiscriminatorColumn(name = "USER_ID", 
contextProperty = "tenant.id") 
@Cacheable(false) 
public class Task implements Serializable { 
... 
CALL DBMS_RLS.ADD_POLICY 
('SCOTT', 'TASK', 'todo_list_policy', 
'SCOTT', 'ident_func', 'select, update, 
delete')); 
<properties> 
<property name="eclipselink.session.customizer" 
value="example.VPDSessionCustomizer" /> 
<property name="eclipselink.session-event-listener" 
value="example.VPDSessionEventAdapter" /> 
<property 
name="eclipselink.jdbc.exclusive-connection.mode" 
value="Always" /> 
</properties>
Hibernate MultiTenantConnectionProvider 
public class MultiTenantProvider 
implements MultiTenantConnectionProvider { 
public Connection getConnection(String tenantIdentifier) throws 
SQLException { 
final Connection connection = getAnyConnection(); 
connection.createStatement().execute( 
"SET SCHEMA '" + tenantIdentifier + "'"); 
return connection; 
} 
public void releaseConnection(String tenantIdentifier, Connection 
connection) throws SQLException { 
releaseAnyConnection(connection); 
} 
}
Hibernate CurrentTenantIdentifierResolver 
public class SchemaResolver implements 
CurrentTenantIdentifierResolver { 
@Override 
public String resolveCurrentTenantIdentifier() { 
return resolveTenant(); 
} 
@Override 
public boolean validateExistingCurrentSessions() { 
return false; 
} 
}
Hibernate persistence.xml 
<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/ 
persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http:// 
java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
<persistence-unit name="default"> 
<properties> 
<property name="javax.persistence.provider" 
value="org.hibernate.ejb.HibernatePersistence" /> 
<property name="hibernate.multiTenancy" value="SCHEMA"/> 
<property name="hibernate.tenant_identifier_resolver" 
value="yourpackage.SchemaResolver"/> 
<property name="hibernate.multi_tenant_connection_provider" 
value="yourpackage.MultiTenantProvider"/> 
</properties> 
</persistence-unit> 
</persistence>
JPA Caching 
• Shared Cache disabled
JPA Caching 
• Shared Cache by tenant
JSF + Multi-tenancy 
• Flexible software architecture 
• Artifacts packaged in separated JAR’s 
• Composition at runtime 
• Templates and contracts 
• Resource library 
• Look-and-feel customization 
• RenderKit features 
• Localization support
JSF Facelets 
The Facelets Gazette 
Site 
Navigation 
●Events 
●Docs 
●Forums 
About Contact Site Map 
Template File name 
_template.html 
Insertion points 
Resources 
css classes, scripts, images
JSF Multi-templating 
• Resource Library Contracts 
• Convention 
• All available contracts discovered at startup 
• Configuration 
• faces-config.xml by <resource-library-contract> 
• contracts attribute in <f:view> 
<web-app-root>/contracts 
contractA 
contractB 
• Declared Templates 
• Declared Insertion contractC 
Points 
• Declared Resources 
• Declared Templates 
• Declared Insertion Points 
• Declared Resources 
• Declared Templates 
• Declared Insertion Points 
• Declared Resources 
JAR files in WEB-INF/lib 
contractD 
contractE 
• Declared Templates 
• Declared Insertion contractF 
Points 
• Declared Resources 
• Declared Templates 
• Declared Insertion Points 
• Declared Resources 
• Declared Templates 
• Declared Insertion Points 
• Declared Resources
JSF Multi-templating 
<web-app-root>/contracts 
contractA 
contractB 
• Declared Templates 
• Declared Insertion contractC 
Points 
• Declared Resources 
• Declared Templates 
• Declared Insertion Points 
• Declared Resources 
• Declared Templates 
• Declared Insertion Points 
• Declared Resources 
JAR files in WEB-INF/lib 
contractD 
contractE 
• Declared Templates 
• Declared Insertion contractF 
Points 
• Declared Resources 
• Declared Templates 
• Declared Insertion Points 
• Declared Resources 
• Declared Templates 
• Declared Insertion Points 
• Declared Resources 
Set of available contracts 
Facelet 1 
<f:view contracts="contractA"> 
... 
faces-config.xml 
Facelet 2 Facelet 3
JSF Multi-templating 
<html xmlns="http://www.w3.org/1999/xhtml” 
xmlns:h="http://java.sun.com/jsf/html” 
xmlns:ui="http://java.sun.com/jsf/ 
facelets"> 
<body> 
<ui:composition template="#{template}”> 
... 
</ui:composition> 
</body> 
</html> 
<?xml version="1.0" encoding="UTF-8"?> 
<web-app> 
<context-param> 
<param-name>javax.faces.view.TEMPLATE</param-name> 
<param-value>mybusiness</param-value> 
</context-param> 
</web-app>
Demo 
• EclipseLink MySports Demo 
• http://wiki.eclipse.org/EclipseLink/Examples/MySports 
• http://git.eclipse.org/c/eclipselink/examples.git
Questions 
?
References 
• http://msdn.microsoft.com/en-us/library/aa479086.aspx 
• https://developers.google.com/appengine/docs/java/multitenancy/ 
• http://www.ibm.com/developerworks/java/library/j-multitenant-java/index.html 
• http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_multitenant.htm 
• http://2012.con-fess.com/sessions/-/details/122/JSF-and-JavaEE-7-for-multi-tenant-applications 
• http://jdevelopment.nl/jsf-22/ 
• http://picketlink.org 
• https://developers.google.com/appengine/docs/java/multitenancy/ 
• http://www.jboss.org/quickstarts/picketlink/picketlink-authentication-idm-multi-tenancy/ 
• http://wiki.eclipse.org/EclipseLink/Examples/MySports
Thank you! 
@rcandidosilva 
rodrigocandido.me

JavaOne 2014 - Supporting Multi-tenancy Applications with Java EE

  • 1.
    Supporting Multi-tenancy Applicationswith Java EE Rodrigo Cândido da Silva @rcandidosilva JavaOne 2014 CON4959
  • 2.
    About Me •Brazilian guy ;) • Work for Integritas company • http://integritastech.com • Software Architect • Java Platform • JUG Leader of GUJavaSC • http://gujavasc.org • Twitter • @rcandidosilva • Personal • http://rodrigocandido.me
  • 3.
    Agenda • CloudServices Model • SaaS Market • Multi-tenancy • Challenges • Pros and Cons • Strategy Types • Java EE + Multi-tenancy • Multi-tenancy at Cloud
  • 4.
  • 5.
  • 6.
    Multi-tenancy • Oneapplication instance to multiple clients (tenant) • Inverse of the multiple instances architecture
  • 7.
  • 8.
    Multi-instances vs. Multi-tenant Feature Multi-instances Multi-tenant Cost Structure Can support only tiered or flat pricing Supports usage based pricing as well as tiered or flat Resources Dedicated resources Shared resources Operation and Maintenance Manage and administer as many instances as customers Manager and administer a single instance for a number of customers Scalable Model Not scalable. As the number of customers increase the maintenance requirements increase proporcionally Scalable, since a number of customers are serviced by one instance
  • 9.
  • 10.
    Challenges • Dataseparation • UI and business rules customization • Access control by tenant • Resource provisioning • Integration • Application update • Failover tolerance
  • 11.
    Pros and Cons • Pros • Low maintenance cost • Same source code for all customers • High scalability • Sharing resources between customers • Cons • High complexity • Separation by tenant-id • More failure risks • If code breaks -> breaks to all customers • Low flexibility available to the customers
  • 12.
    Multi-tenancy • Adoptionlevels • Level 1 (Customized) • [N] applications and [N] databases • Level 2 (Configurable) • [1] application and [N] databases • Level 3 (Scalable) • [1] application and [1] database
  • 13.
    Level 1 -Customized • [N] applications and [N] databases
  • 14.
    Level 2 -Configurable • [1] application and [N] databases
  • 15.
    Level 3 -Scalable • [1] application and [1] database
  • 16.
    What is theBest Choice? • Depends on… • Data Customization • Addition or removal of columns in the data store • Function Customization • The functionality executed for a specific business can vary by customers • Process Customization • The business process can vary for each customer • Licensing Features • The product has multiple licenses which define the functionality that is enabled for the customer
  • 17.
    Database Strategy SeparateDatabases Separate Tables Shared Database
  • 18.
    Database Strategy FeatureSeparate DBs Separate Tables Shared Database Data Customization Security Inter-dependency and Performance Scalable Model Customer On-boarding
  • 19.
    Java EE +Multi-tenancy • Database • JPA + Multi-tenancy • UI Customization • JSF + Multi-tenancy • Java EE 8 with Cloud support
  • 20.
    JPA + Multi-tenancy • There is no standard at this time • EclipseLink • Multi-tenancy support using @Multitenant • Multitenant strategies • @Multitenant(SINGLE_TABLE) – default • @Multitenant(TABLE_PER_TENANT) • @Multitenant(VPD) • Hibernate • Supports tenant identifier features • MultiTenantConnectionProvider • CurrentTenantIdentifierResolver
  • 21.
    EclipseLink SINGLE_TABLE @Entity @Table(name=“EMP”) @Multitenant(SINGLE_TABLE) @TenantDiscriminatorColumn(name = “TENANT_ID”, contextProperty = “tenant-id”) public class Employee { ... } HashMap properties = new HashMap(); properties.put("tenant.id", "707"); ... EntityManager em = Persistence .createEntityManagerFactory( "multi-tenant”,properties) .createEntityManager(); <persistence-unit name="multi-tenant"> ... <properties> <property name="tenant.id" value="707"/> ... </properties> </persistence-unit>
  • 22.
    EclipseLink TABLE_PER_TENANT <entityclass="Employee"> <multitenant type="TABLE_PER_TENANT"> <tenant-table-discriminator type="SCHEMA" context-property=" eclipselink.tenant-id"/> </multitenant> <table name="EMP"> ... </entity> @Entity @Table(name=“EMP”) @Multitenant(TABLE_PER_TENANT) @TenantTableDiscriminator(type=SCHEMA, contextProperty="eclipselink.tenant-id") public class Employee { ... }
  • 23.
    EclipseLink VPD @Entity @Multitenant @TenantDiscriminatorColumn(name = "USER_ID", contextProperty = "tenant.id") @Cacheable(false) public class Task implements Serializable { ... CALL DBMS_RLS.ADD_POLICY ('SCOTT', 'TASK', 'todo_list_policy', 'SCOTT', 'ident_func', 'select, update, delete')); <properties> <property name="eclipselink.session.customizer" value="example.VPDSessionCustomizer" /> <property name="eclipselink.session-event-listener" value="example.VPDSessionEventAdapter" /> <property name="eclipselink.jdbc.exclusive-connection.mode" value="Always" /> </properties>
  • 24.
    Hibernate MultiTenantConnectionProvider publicclass MultiTenantProvider implements MultiTenantConnectionProvider { public Connection getConnection(String tenantIdentifier) throws SQLException { final Connection connection = getAnyConnection(); connection.createStatement().execute( "SET SCHEMA '" + tenantIdentifier + "'"); return connection; } public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException { releaseAnyConnection(connection); } }
  • 25.
    Hibernate CurrentTenantIdentifierResolver publicclass SchemaResolver implements CurrentTenantIdentifierResolver { @Override public String resolveCurrentTenantIdentifier() { return resolveTenant(); } @Override public boolean validateExistingCurrentSessions() { return false; } }
  • 26.
    Hibernate persistence.xml <?xmlversion="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/ persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http:// java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="default"> <properties> <property name="javax.persistence.provider" value="org.hibernate.ejb.HibernatePersistence" /> <property name="hibernate.multiTenancy" value="SCHEMA"/> <property name="hibernate.tenant_identifier_resolver" value="yourpackage.SchemaResolver"/> <property name="hibernate.multi_tenant_connection_provider" value="yourpackage.MultiTenantProvider"/> </properties> </persistence-unit> </persistence>
  • 27.
    JPA Caching •Shared Cache disabled
  • 28.
    JPA Caching •Shared Cache by tenant
  • 29.
    JSF + Multi-tenancy • Flexible software architecture • Artifacts packaged in separated JAR’s • Composition at runtime • Templates and contracts • Resource library • Look-and-feel customization • RenderKit features • Localization support
  • 30.
    JSF Facelets TheFacelets Gazette Site Navigation ●Events ●Docs ●Forums About Contact Site Map Template File name _template.html Insertion points Resources css classes, scripts, images
  • 31.
    JSF Multi-templating •Resource Library Contracts • Convention • All available contracts discovered at startup • Configuration • faces-config.xml by <resource-library-contract> • contracts attribute in <f:view> <web-app-root>/contracts contractA contractB • Declared Templates • Declared Insertion contractC Points • Declared Resources • Declared Templates • Declared Insertion Points • Declared Resources • Declared Templates • Declared Insertion Points • Declared Resources JAR files in WEB-INF/lib contractD contractE • Declared Templates • Declared Insertion contractF Points • Declared Resources • Declared Templates • Declared Insertion Points • Declared Resources • Declared Templates • Declared Insertion Points • Declared Resources
  • 32.
    JSF Multi-templating <web-app-root>/contracts contractA contractB • Declared Templates • Declared Insertion contractC Points • Declared Resources • Declared Templates • Declared Insertion Points • Declared Resources • Declared Templates • Declared Insertion Points • Declared Resources JAR files in WEB-INF/lib contractD contractE • Declared Templates • Declared Insertion contractF Points • Declared Resources • Declared Templates • Declared Insertion Points • Declared Resources • Declared Templates • Declared Insertion Points • Declared Resources Set of available contracts Facelet 1 <f:view contracts="contractA"> ... faces-config.xml Facelet 2 Facelet 3
  • 33.
    JSF Multi-templating <htmlxmlns="http://www.w3.org/1999/xhtml” xmlns:h="http://java.sun.com/jsf/html” xmlns:ui="http://java.sun.com/jsf/ facelets"> <body> <ui:composition template="#{template}”> ... </ui:composition> </body> </html> <?xml version="1.0" encoding="UTF-8"?> <web-app> <context-param> <param-name>javax.faces.view.TEMPLATE</param-name> <param-value>mybusiness</param-value> </context-param> </web-app>
  • 34.
    Demo • EclipseLinkMySports Demo • http://wiki.eclipse.org/EclipseLink/Examples/MySports • http://git.eclipse.org/c/eclipselink/examples.git
  • 35.
  • 36.
    References • http://msdn.microsoft.com/en-us/library/aa479086.aspx • https://developers.google.com/appengine/docs/java/multitenancy/ • http://www.ibm.com/developerworks/java/library/j-multitenant-java/index.html • http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_multitenant.htm • http://2012.con-fess.com/sessions/-/details/122/JSF-and-JavaEE-7-for-multi-tenant-applications • http://jdevelopment.nl/jsf-22/ • http://picketlink.org • https://developers.google.com/appengine/docs/java/multitenancy/ • http://www.jboss.org/quickstarts/picketlink/picketlink-authentication-idm-multi-tenancy/ • http://wiki.eclipse.org/EclipseLink/Examples/MySports
  • 37.
    Thank you! @rcandidosilva rodrigocandido.me