Documente Academic
Documente Profesional
Documente Cultură
www.devmedia.com.br
[verso para impresso]
Link original: http://www.devmedia.com.br/articles/viewcomp.asp?comp=29114
Introduo a Multi-Tenancy
com Hibernate 4
Este artigo apresenta a funcionalidade, do Hibernate, que
prov mecanismos de suporte arquitetura Multi-Tenant.
Artigo do tipo Tutorial
Recursos especiais neste artigo:
Contedo sobre Novidades
Autores: Marcos de Melo Siega e Everton Coimbra de Arajo
Suporte a Multi-Tenancy com Hibernate 4
Este artigo apresenta a funcionalidade, agregada verso 4 do framework Hibernate, que
prov mecanismos de suporte arquitetura Multi-Tenant (vrios clientes, logicamente
isolados, utilizando os mesmos recursos fsicos). Alm de demonstrar os aspectos deste
novo recurso, expe-se uma contextualizao sobre Hibernate e Multi-Tenancy, e ento,
ao final, implementa-se um exemplo prtico utilizando esta nova funcionalidade.
Em que situao o tema til
Arquitetos de software encontram grandes desafios ao construir modelos arquiteturais
SaaS (Software como servio, do ingls Software as a Service) que apresentem uma
infraestrutura de dados diferenciada, podendo no contar com servidores locais e
infraestrutura prpria, tendo que dispor todos os dados em um espao compartilhado.
Fatores como estes influenciam diretamente na capacidade de gerncia, monitoramento e
at mesmo na segurana dos dados.
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
1/23
29/7/2014
Hibernate
O Hibernate um framework para mapeamento objeto relacional e consulta a bases de
dados de cdigo aberto e que distribudo sob a licena LGPL. Ele assegura a
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
2/23
29/7/2014
O que Multi-Tenancy?
Em uma aplicao que atende diversos clientes simultaneamente, fundamental que uma
possvel falha na operao de um cliente no afete os demais. Desta maneira, em
modelos onde os recursos computacionais so amplamente compartilhados, este cenrio
requer uma ateno especial.
Para as organizaes, mecanismos que garantam a integridade dos dados, seu mais
importante acervo, so extremamente importantes. Por este motivo, elas preferem
manter seus softwares e bancos de dados instalados em hardwares pertencentes
prpria organizao, a ter que confi-los a estruturas inadequadas de fornecedores de
hospedagem.
Com o advento da computao em nuvem, e a tendncia de novas aplicaes operarem e
serem disponibilizadas, cada vez mais, por esta tecnologia, modelos arquiteturais
adequados que forneam apoio integridade dos dados se tornam imprescindveis.
Diante deste cenrio, onde a utilizao dos recursos fsicos feita de maneira
compartilhada e a garantia de integridade e segurana dos dados vital, uma soluo
tem ganhado destaque por permitir o isolamento lgico dos recursos. Esta soluo o
modelo chamado de Multi-Tenancy.
O termo Multi-Tenancy aplicado ao desenvolvimento de software para indicar uma
arquitetura na qual uma nica instncia de determinada aplicao serve simultaneamente
a vrios clientes (tenants). Cada um dos clientes pode receber a habilidade de customizar
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
3/23
29/7/2014
partes da aplicao, tais como a cor da interface com o usurio ou as regras de negcio
(por meio de configuraes), porm, no so capazes de modificar o cdigo do aplicativo.
Este modelo arquitetural comumente utilizado em solues SaaS para isolar as
informaes (dados, armazenados em um banco de dados, e customizaes, por
exemplo) dos diferentes clientes. O uso desse modelo para tal propsito comumente
chamado de Multi-Tenant de dados.
Multi-Tenancy no Hibernate
Como de costume, o Hibernate se esfora para manter a API simples e isolada de
qualquer detalhe da complexidade de sua implementao. Neste sentido, o uso deste
novo recurso resume-se basicamente a especificar o identificador do cliente no processo
de abertura de uma nova sesso (session) e indicar, no processo de configurao do
framework, a estratgia que ser adotada para isolar os dados.
Entre as diferentes estratgias de implementao do Multi-Tenancy, esto as seguintes:
1. Criar um banco de dados ou esquema de dados exclusivo para cada cliente;
2. Usar o mesmo banco de dados ou esquema para todos os clientes, mas com uma
coluna adicional em todas as tabelas (um id_tenant, por exemplo) para filtrar os dados.
O Hibernate, em sua verso 4, suporta apenas o primeiro item. O suporte para o
segundo est planejado para acompanhar a verso 5.0 do framework.
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
4/23
29/7/2014
5/23
29/7/2014
Adota-se este modelo atravs da definio de um pool de conexes JDBC por cliente, de
modo que a seleo do pool a ser utilizado ocorre com base em um identificador
associado ao usurio logado.
Figura 2. Base de dados compartilhada por vrios clientes com separao por
esquemas.
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
6/23
29/7/2014
Ao empregar este modelo, teremos duas maneiras distintas para definir as conexes
JDBC:
1. As conexes podem apontar especificamente para cada esquema, de maneira anloga
ao modelo de banco de dados exclusivo por cliente. Contudo, este mtodo s pode ser
adotado se o driver de conexo com a base de dados suportar a nomeao do esquema
padro por meio de sua URL, ou se o mecanismo de pooling suportar a nomeao de um
esquema para utilizar suas conexes. Ao empregar este mtodo, haver um pool de
conexes JDBC distinto por cliente, onde o pool a ser utilizado selecionado com base
no identificador associado ao cliente logado;
2. As conexes poderiam apontar para a prpria base de dados (utilizando algum
esquema padro), e a mudana de esquema ocorreria atravs do uso do comando SQL
SET SCHEMA (ou similar) pela aplicao. Ao utilizar esta tcnica, apenas um pool de
conexes JDBC delegado para atender a todos os clientes, e antes de ocorrer o
consumo da conexo, haveria a alterao para o esquema nomeado com o identificador
associado ao cliente logado na aplicao.
7/23
29/7/2014
Aps a definio dos esquemas, vamos criar uma tabela em cada um deles. Para o
exemplo, nomearemos estas tabelas como Pessoa, e ambas tero a mesma estrutura.
A Listagem 2 apresenta as instrues utilizadas na criao das tabelas. Cada uma
possui, basicamente, dois atributos, um identificador e um nome. Decidiu-se por replicar
a estrutura nos dois esquemas apenas para facilitar a apresentao do exemplo.
Listagem 2. Instrues utilizadas na criao das tabelas.
Criao do projeto
Para comear, preciso criar um novo projeto do tipo Java Project no Eclipse e definir
algumas caractersticas da aplicao. Assim, deve-se nomear o projeto, definir sua
localizao, o ambiente de execuo e optar por um layout para separar adequadamente
os arquivos de extenso .class e .java, como demonstrado na Figura 3.
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
8/23
29/7/2014
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
9/23
29/7/2014
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
10/23
29/7/2014
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
11/23
29/7/2014
12/23
29/7/2014
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="MultiTenancyApp">
</persistence-unit>
</persistence>
13/23
29/7/2014
Para comear, uma nova classe Java, denominada Pessoa, deve ser criada. Esta classe
ter a finalidade de representar a tabela presente em ambos os esquemas do banco de
dados. Feito isto, faz-se necessrio implement-la, definindo seus atributos, mtodos
acessores e mapeando-a com anotaes, conforme realizado na Listagem 5. E vlido
lembrar tambm de mape-la no arquivo persistence.xml, para que a unidade de
persistncia consiga gerenci-la.
Listagem 5. Implementao da classe Pessoa.
package br.edu.utfpr.modelo;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
//Mapeamento da classe com sua representao na base de dados
@Entity(name = "Pessoa")
public class Pessoa implements Serializable {
private static final long serialVersionUID = 1L;
//Definio de atributo identificador
@Id
private Long id;
private String nome;
// Mtodos get/set omitidos
}
14/23
29/7/2014
com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/cliente1</property>
<property name="hibernate.connection.username">
user</property>
<property name="hibernate.connection.password">
Password</property>
<property name="hibernate.hbm2ddl.auto">
create-drop</property>
<property name="hibernate.show_sql">
true</property>
<property name="hibernate.format_sql">
true</property>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.multiTenancy">
schema</property>
<property name="hibernate.multi_tenant_connection_provider">
br.edu.utfpr.application.MultiTenantConnectionProviderImpl</property>
<mapping class="br.edu.utfpr.modelo.Pessoa" />
</session-factory>
</hibernate-configuration>
15/23
29/7/2014
package br.edu.utfpr.application;
import java.util.Properties;
import org.hibernate.cfg.Environment;
import org.hibernate.service.jdbc.connections.internal
.DriverManagerConnectionProviderImpl;
//Classe responsvel por prover conexo com o banco de dados a partir de
//configuraes e propriedades
public class ConnectionProviderBuilder {
//Constantes utilizadas para configurao da conexo com a base de dados.
public static final String DRIVER = "com.mysql.jdbc.Driver";
//Para este exemplo assumiu-se o esquema cliente1 como default.
public static final String URL =
"jdbc:mysql://localhost:3306/cliente1";
public static final String USER = "user";
public static final String PASS = "password";
public static Properties getConnectionProviderProperties
(String dbName) {
Properties props = new Properties(null);
props.put(Environment.DRIVER, DRIVER);
props.put(Environment.URL, String.format(URL, dbName));
props.put(Environment.USER, USER);
props.put(Environment.PASS, PASS);
return props;
}
private static DriverManagerConnectionProviderImpl
buildConnectionProvider(
Properties props, final boolean allowAggressiveRelease) {
DriverManagerConnectionProviderImpl connectionProvider =
new DriverManagerConnectionProviderImpl() {
public boolean supportsAggressiveRelease() {
return allowAggressiveRelease;
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
16/23
29/7/2014
}
};
connectionProvider.configure(props);
return connectionProvider;
}
}
package br.edu.utfpr.application;
import java.sql.Connection;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.service.jdbc.connections.spi.MultiTenantConnectionProvider;
//Classe responsvel por prover conexes baseadas nos identificadores
// dos clientes
public class MultiTenantConnectionProviderImpl implements
MultiTenantConnectionProvider {
//Definio da instncia da classe construtora de provedores de conexo
private final ConnectionProvider connectionProvider =
ConnectionProviderBuilder
.buildConnectionProvider("cliente1");
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
17/23
29/7/2014
18/23
29/7/2014
}
//Mtodos no utilizados neste exemplo, mas que precisam ser sobrescritos.
@Override
public boolean isUnwrappableAs(@SuppressWarnings("rawtypes")
Class arg0) {
@Override
public <T> T unwrap(Class<T> arg0) {
@Override
public boolean supportsAggressiveRelease() {
}
Para finalizar, prope-se a criao de uma classe para inserir alguns registros na base de
dados, apenas para demonstrar o uso da funcionalidade de Multi-Tenancy. A
implementao desta visa obter sesses de acordo com o inquilino desejado e realizar
inseres utilizando a sesso adquirida. A Listagem 9 apresenta o cdigo dessa classe.
Um detalhe importante nesta classe a definio do mtodo
configureSessionFactory(), que segue o novo modelo definido pelo Hibernate para
obteno de uma SessionFactory. Seu funcionamento baseia-se essencialmente na
utilizao do arquivo XML de propriedades para configurar novas fbricas de sesso.
Listagem 9. Cdigo da classe de testes MultiTenancyEsquemaExclusivo.
package br.edu.utfpr.application;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import br.edu.utfpr.modelo.Pessoa;
public class MultiTenancyEsquemaExclusivo {
// Fbrica de sesses
private static SessionFactory sessionFactory;
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
19/23
29/7/2014
20/23
29/7/2014
A Listagem 11 apresenta duas consultas feitas nas tabelas para checar os resultados
das inseres. Como pode ser visto a partir dos registros retornados, as aes de
insero foram bem sucedidas.
Listagem 11. Resultado das consultas realizadas nas tabelas de cada cliente.
+----+------------+
| 1 + Tenant One |
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
21/23
29/7/2014
+----+------------+
mysql> USE cliente2;
mysql> SELECT * FROM Pessoa;
+----+------------+
| id | nome
+----+------------+
| 1 + Tenant Two |
+----+------------+
Concluso
Este artigo apresentou as opes de suporte que o framework Hibernate, na verso 4,
oferece ao modelo arquitetural Multi-Tenant. Foram descritas algumas das caractersticas
presentes na nova verso da ferramenta e um dos recursos adicionados foi trabalhado
em um exemplo prtico.
Alm de expor variaes do modelo Multi-Tenant, foi construda uma aplicao a fim de
exemplificar a atuao do framework sobre uma destas alternativas. O modelo escolhido
define que cada cliente possui um esquema exclusivo em uma base de dados
compartilhada.
O exemplo abordado serve para compreender e aplicar a soluo em um dos possveis
modelos de arquitetura, porm, cabe ao arquiteto do sistema optar pela opo que
melhor se ajusta s necessidades do projeto, levando em considerao os fatores
positivos e negativos relacionados sua adoo.
Dentre as principais vantagens associadas ao emprego de uma soluo Multi-Tenant,
destacam-se a significativa reduo de custos com recursos fsicos, devido ao
compartilhamento e reutilizao de infraestrutura de hardware, e a integridade dos dados
dos diversos clientes, garantida pelo isolamento que os modelos proporcionam.
Em contrapartida, podem ser considerados aspectos negativos: a dificuldade de calcular
os recursos necessrios para cada novo cliente, garantindo que os demais inquilinos no
sofram influncia negativa desta incluso, e o risco associado a uma possvel falha nos
recursos de uso compartilhado, que pode acabar afetando vrios clientes e ocasionar
uma perda de grandes volumes de dados.
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
22/23
29/7/2014
Links
Hibernate Community Documentation Multi-Tenancy
http://docs.jboss.org/hibernate/core/4.1/devguide/en-US/html/ch16.html
Hibernate 4: multitenancy, extenses, OSGI e uma entrevista com o lder do
projeto
http://www.infoq.com/br/news/2012/01/hibernate-4
Multi-Tenant Data Architecture
http://msdn.microsoft.com/en-us/library/aa479086.aspx
Using Hibernate to Implement Multi-Tenant Cloud Architecture
http://www.devx.com/Java/Article/47817/0/page/2
What is Hibernate
http://onjava.com/pub/a/onjava/2005/09/21/what-is-hibernate.html
Hibernate JavaDoc 4.1
http://docs.jboss.org/hibernate/orm/4.1/javadocs/
Hibernate JBoss Community
http://www.hibernate.org
http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114
23/23