23
29/7/2014 Introdução a Multi-Tenancy com Hibernate 4 http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 1/23 www.devmedia.com.br [versão para impressão] Link original: http://www.devmedia.com.br/articles/viewcomp.asp?comp=29114 Introdução 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: Conteúdo sobre Novidades Autores: Marcos de Melo Siega e Everton Coimbra de Araújo Suporte a Multi-Tenancy com Hibernate 4 Este artigo apresenta a funcionalidade, agregada à versão 4 do framework Hibernate, que provê mecanismos de suporte à arquitetura Multi-Tenant (vários clientes, logicamente isolados, utilizando os mesmos recursos físicos). Além de demonstrar os aspectos deste novo recurso, expõe-se uma contextualização sobre Hibernate e Multi-Tenancy, e então, ao final, implementa-se um exemplo prático utilizando esta nova funcionalidade. Em que situação o tema é útil Arquitetos de software encontram grandes desafios ao construir modelos arquiteturais SaaS (Software como serviço, do inglês Software as a Service) que apresentem uma infraestrutura de dados diferenciada, podendo não contar com servidores locais e infraestrutura própria, tendo que dispor todos os dados em um espaço compartilhado. Fatores como estes influenciam diretamente na capacidade de gerência, monitoramento e até mesmo na segurança dos dados.

Introdução a Multi-Tenancy Com Hibernate 4

Embed Size (px)

DESCRIPTION

multi tenancy

Citation preview

Page 1: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 1/23

www.devmedia.com.br [versão para impressão]Link original: http://www.devmedia.com.br/articles/viewcomp.asp?comp=29114

Introdução a Multi-Tenancycom Hibernate 4

Este artigo apresenta a funcionalidade, do Hibernate, queprovê mecanismos de suporte à arquitetura Multi-Tenant.

Artigo do tipo Tutorial

Recursos especiais neste artigo:

Conteúdo sobre Novidades

Autores: Marcos de Melo Siega e Everton Coimbra de Araújo

Suporte a Multi-Tenancy com Hibernate 4

Este artigo apresenta a funcionalidade, agregada à versão 4 do framework Hibernate, que

provê mecanismos de suporte à arquitetura Multi-Tenant (vários clientes, logicamente

isolados, utilizando os mesmos recursos físicos). Além de demonstrar os aspectos deste

novo recurso, expõe-se uma contextualização sobre Hibernate e Multi-Tenancy, e então,

ao final, implementa-se um exemplo prático utilizando esta nova funcionalidade.

Em que situação o tema é útil

Arquitetos de software encontram grandes desafios ao construir modelos arquiteturais

SaaS (Software como serviço, do inglês Software as a Service) que apresentem uma

infraestrutura de dados diferenciada, podendo não contar com servidores locais e

infraestrutura própria, tendo que dispor todos os dados em um espaço compartilhado.

Fatores como estes influenciam diretamente na capacidade de gerência, monitoramento e

até mesmo na segurança dos dados.

Page 2: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 2/23

Na medida em que a linguagem Java começou a ganhar destaque em ambientes

corporativos, notou-se rapidamente que um tempo excessivo era gasto com a

codificação de instruções SQL e com código JDBC capaz de interpretá-las.

O processo de desenvolvimento sofre influência direta deste aspecto negativo, pois há

uma imensa queda de produtividade quando o desenvolvedor torna-se responsável por

criar tais instruções manualmente, cabendo a ele tratar da mudança do paradigma

orientado a objetos para o mapeamento objeto relacional e vice-versa. Este

procedimento implica na necessidade de escrita de muitas linhas de código, criando um

enorme obstáculo para o desenvolvedor, que ficará encarregado de tratar da persistência

e recuperação de seus objetos utilizando uma linguagem de consulta estruturada.

A existência desta divergência entre o modelo orientado a objetos e o modelo relacional

estimulou o desenvolvimento de mecanismos que contornassem este problema. Uma das

principais ferramentas que surgiram, buscando resolver esta incompatibilidade, foi o

Hibernate. Este framework aplica técnicas de mapeamento objeto relacional para resolver

a dissonância entre os modelos.

Os frameworks de mapeamento objeto relacional, como o Hibernate, permitem mapear a

representação dos dados de um modelo de objeto para um modelo de dados relacional e

seu respectivo esquema de banco de dados, utilizando arquivos de configuração no

formato XML e anotações Java.

Tais ferramentas de ORM, além de tratar da persistência e recuperação dos dados,

devem garantir que as informações permaneçam íntegras e seguras, seja qual for a

arquitetura de software adotada para a solução. Diante da constante necessidade de

garantia destes fatores nos mais variados contextos, a versão 4 do Hibernate oferece

suporte para uma das arquiteturas que tem ganhado bastante destaque, denominada

Multi-Tenancy. Este novo recurso vai de encontro ao aumento do número de aplicações

que estão sendo desenvolvidas voltadas para a nuvem, ou ambientes onde os recursos

disponíveis são compartilhados.

Com base nisso, este artigo aborda as principais características deste recurso adicionado

ao Hibernate, suas possíveis aplicações e um exemplo simples de como empregá-lo.

Hibernate

O Hibernate é um framework para mapeamento objeto relacional e consulta a bases de

dados de código aberto e que é distribuído sob a licença LGPL. Ele assegura a

Page 3: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 3/23

transparência no processo de armazenamento de objetos em bancos de dados

relacionais para o desenvolvedor, tirando dele a necessidade de se preocupar com a

forma com que estes objetos serão persistidos ou recuperados. Esta transparência

permite que o desenvolvedor concentre-se somente nas características e nos problemas

a serem resolvidos pela aplicação.

O Hibernate possibilita que os desenvolvedores utilizem a convenção POJO (Objetos

Simples em Java, do inglês Plain Old Java Objects) para construir a camada de modelo

das aplicações. No entanto, ele não é apenas uma solução ORM, mas sim uma coleção de

projetos que fornecem funcionalidades que vão além do mapeamento objeto relacional.

Uma dessas funcionalidades é o suporte ao isolamento de dados para os vários clientes

de uma aplicação, também conhecido como Multi-Tenancy, sobre o qual abordaremos a

partir de agora.

O que é Multi-Tenancy?

Em uma aplicação que atende diversos clientes simultaneamente, é fundamental que uma

possível falha na operação de um cliente não afete os demais. Desta maneira, em

modelos onde os recursos computacionais são amplamente compartilhados, este cenário

requer uma atenção especial.

Para as organizações, mecanismos que garantam a integridade dos dados, seu mais

importante acervo, são extremamente importantes. Por este motivo, elas preferem

manter seus softwares e bancos de dados instalados em hardwares pertencentes à

própria organização, a ter que confiá-los a estruturas inadequadas de fornecedores de

hospedagem.

Com o advento da computação em nuvem, e a tendência de novas aplicações operarem e

serem disponibilizadas, cada vez mais, por esta tecnologia, modelos arquiteturais

adequados que forneçam apoio à integridade dos dados se tornam imprescindíveis.

Diante deste cenário, onde a utilização dos recursos físicos é feita de maneira

compartilhada e a garantia de integridade e segurança dos dados é vital, uma solução

tem ganhado destaque por permitir o isolamento lógico dos recursos. Esta solução é o

modelo chamado de Multi-Tenancy.

O termo Multi-Tenancy é aplicado ao desenvolvimento de software para indicar uma

arquitetura na qual uma única instância de determinada aplicação serve simultaneamente

a vários clientes (tenants). Cada um dos clientes pode receber a habilidade de customizar

Page 4: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 4/23

partes da aplicação, tais como a cor da interface com o usuário ou as regras de negócio

(por meio de configurações), porém, não são capazes de modificar o código do aplicativo.

Este modelo arquitetural é comumente utilizado em soluções SaaS para isolar as

informações (dados, armazenados em um banco de dados, e customizações, por

exemplo) dos diferentes clientes. O uso desse modelo para tal propósito é comumente

chamado de “Multi-Tenant de dados”.

Multi-Tenancy no Hibernate

Como de costume, o Hibernate se esforça para manter a API simples e isolada de

qualquer detalhe da complexidade de sua implementação. Neste sentido, o uso deste

novo recurso resume-se basicamente a especificar o identificador do cliente no processo

de abertura de uma nova sessão (session) e indicar, no processo de configuração do

framework, a estratégia que será adotada para isolar os dados.

Entre as diferentes estratégias de implementação do Multi-Tenancy, estão 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 versão 4, suporta apenas o primeiro item. O suporte para o

segundo está planejado para acompanhar a versão 5.0 do framework.

Banco de dados exclusivo por cliente

Nesta abordagem, os dados de cada cliente são mantidos em uma instância de banco de

dados separada fisicamente, como demonstra a Figura 1.

Page 5: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 5/23

Figura 1. Base de dados exclusiva por cliente.

Neste modelo, conexões JDBC apontam especificamente para cada banco de dados.

Deste modo, cada cliente utilizará apenas a conexão que lhe pertence, e as modificações

feitas por cada um dos inquilinos não afetará os dados e configurações dos demais.

Page 6: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 6/23

Adota-se este modelo através da definição de um pool de conexões JDBC por cliente, de

modo que a seleção do pool a ser utilizado ocorre com base em um identificador

associado ao usuário logado.

Esquema exclusivo por cliente

Nesta abordagem, os dados de cada cliente são mantidos em diferentes esquemas de

uma instância compartilhada de banco de dados, conforme ilustra a Figura 2.

Figura 2. Base de dados compartilhada por vários clientes com separação por

esquemas.

Page 7: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 7/23

Ao empregar este modelo, teremos duas maneiras distintas para definir as conexões

JDBC:

1. As conexões podem apontar especificamente para cada esquema, de maneira análoga

ao modelo de banco de dados exclusivo por cliente. Contudo, este método só pode ser

adotado se o driver de conexão com a base de dados suportar a nomeação do esquema

padrão por meio de sua URL, ou se o mecanismo de pooling suportar a nomeação de um

esquema para utilizar suas conexões. Ao empregar este método, haverá um pool de

conexões JDBC distinto por cliente, onde o pool a ser utilizado é selecionado com base

no identificador associado ao cliente logado;

2. As conexões poderiam apontar para a própria base de dados (utilizando algum

esquema padrão), e a mudança de esquema ocorreria através do uso do comando SQL

SET SCHEMA (ou similar) pela aplicação. Ao utilizar esta técnica, apenas um pool de

conexões JDBC é delegado para atender a todos os clientes, e antes de ocorrer o

consumo da conexão, haveria a alteração para o esquema nomeado com o identificador

associado ao cliente logado na aplicação.

Implementação do modelo Multi-Tenancy comHibernate

A fim de ilustrar o suporte ao modelo Multi-Tenancy, propõe-se a criação de uma

aplicação de exemplo, onde a abordagem adotada será a de esquema exclusivo por

cliente. A solução proposta terá como finalidade realizar a persistência de dados de

acordo com tal separação e apresentar os resultados obtidos. Antes de começar a

desenvolver esta solução, no entanto, faz-se necessário obter todos os arquivos citados

a seguir.

Para contar com o Hibernate é preciso baixar os arquivos do framework e colocá-los no

classpath da aplicação. Tais arquivos podem ser obtidos no site oficial da ferramenta (ver

seção Links). Lá se encontram também instruções sobre como utilizá-la adequadamente.

No exemplo trabalhado, optou-se pelo uso do MySQL, mas nada impede que o

desenvolvedor utilize outro SGBD. A adoção do MySQL cria a necessidade de obter e

adicionar o arquivo JAR correspondente ao seu driver no diretório lib, além de incluí-lo no

classpath, do mesmo modo como foram adicionados os arquivos do Hibernate.

Assim, com o ambiente de desenvolvimento instalado e corretamente configurado, pode

ser dado início ao processo de implementação da aplicação exemplo.

Page 8: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 8/23

Criação dos esquemas e tabelas

Antes de começar a implementação do projeto, utiliza-se a ferramenta MySQL Command

Line Client para criar dois esquemas na instância do MySQL. Cada um dos esquemas

definidos pertencerá exclusivamente ao cliente cujo nome lhe identifica. A Listagem 1

demonstra os comandos utilizados para este processo.

Listagem 1. Instruções utilizadas para a criação dos esquemas.

mysql> CREATE SCHEMA cliente1;

mysql> CREATE SCHEMA cliente2;

Após a definição dos esquemas, vamos criar uma tabela em cada um deles. Para o

exemplo, nomearemos estas tabelas como Pessoa, e ambas terão a mesma estrutura.

A Listagem 2 apresenta as instruções utilizadas na criação 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 apresentação do exemplo.

Listagem 2. Instruções utilizadas na criação das tabelas.

mysql> CREATE TABLE ‘cliente1’.’pessoa’ ( ‘id’ INT NOT NULL, ‘nome’ VARCHAR(45)

NULL, PRIMARY KEY(‘id’));

mysql> CREATE TABLE ‘cliente2’.’pessoa’ ( ‘id’ INT NOT NULL, ‘nome’ VARCHAR(45)

NULL, PRIMARY KEY(‘id’));

Com a base de dados configurada e seus esquemas definidos, pode-se iniciar o

desenvolvimento da aplicação que utilizará a funcionalidade de Multi-Tenancy.

Criação do projeto

Para começar, é preciso criar um novo projeto do tipo Java Project no Eclipse e definir

algumas características da aplicação. Assim, deve-se nomear o projeto, definir sua

localização, o ambiente de execução e optar por um layout para separar adequadamente

os arquivos de extensão .class e .java, como demonstrado na Figura 3.

Page 9: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 9/23

Figura 3. Janela do wizard para criação de um novo projeto.

Para finalizar este processo, especifique as bibliotecas que serão adicionadas ao

classpath, a fim de atender os requisitos de dependência da nova aplicação, como

realizado na Figura 4. Caso as bibliotecas não estejam disponíveis para seleção, o

desenvolvedor pode facilmente configurá-las utilizando a opção User Libraries.

Page 10: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 10/23

Figura 4. Janela do wizard para definição das configurações de construção do projeto.

Além de adicionar as bibliotecas no classpath, também é importante colocar tais arquivos

(JARs do Hibernate e do MySQL) na pasta lib do projeto. Caso a IDE não crie tal pasta

automaticamente, o desenvolvedor deve criá-la manualmente.

O processo de adição de tais arquivos pode ser realizado por meio da técnica de Drag-

and-Drop (Arrastar e Soltar). O resultado de tal procedimento é apresentado na Figura

5.

Page 11: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 11/23

Figura 5. Resultado da adição dos arquivos de dependência no projeto.

Neste momento, após ter criado o projeto, faz-se necessário definir uma faceta para ele.

Facetas permitem que projetos Java EE obtenham, através de configuração, suporte para

várias outras tecnologias. O uso deste recurso deve-se pelo emprego da IDE Eclipse,

sendo que outros ambientes de desenvolvimento não agregam tal conceito. A este

exemplo foi adicionada a faceta JPA, como exposto na Figura 6.

Page 12: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 12/23

Figura 6. Janela do wizard de configuração das propriedades do projeto.

A seleção desta faceta obriga o desenvolvedor a realizar algumas configurações básicas,

tais como, indicar a biblioteca que contém os arquivos de implementação do JPA e ajustar

a conexão com a base de dados utilizada. Um link (Further configuration required...)

emitido pela própria IDE e que estará disponível, em destaque, na parte inferior da janela

do Wizard de ajustes das propriedades do projeto, dá acesso às propriedades da

conexão, que deve ser configurada. O resultado dessa etapa pode ser observado na

Listagem 3.

Listagem 3. Arquivo persistence.xml gerado automaticamente após o processo de

configuração da faceta JPA.

<?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"

Page 13: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 13/23

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>

Como resultado do processo de configuração o arquivo persistence.xml é gerado, e deve

ser modificado de acordo com as propriedades do banco de dados e seguindo o padrão

definido pelo provedor de persistência. A Listagem 4 apresenta o resultado de tal

procedimento.

Listagem 4. Configuração do arquivo 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="MultiTenancyApp"

transaction-type="RESOURCE_LOCAL">

<provider>

org.hibernate.ejb.HibernatePersistence</provider>

<properties>

<property name="hibernate.connection.driver_class"

value="com.mysql.jdbc.Driver" />

<property name="hibernate.connection.url"

value="jdbc:mysql://localhost:3306/cliente1" />

<property name="hibernate.connection.username" value="user" />

<property name="hibernate.connection.password" value="password" />

<property name="hibernate.multiTenancy" value="SCHEMA" />

</properties>

</persistence-unit>

</persistence>

Implementação da aplicação exemplo

Tendo criado o projeto e realizadas as devidas configurações, dá-se início ao

desenvolvimento da classe que demonstrará o uso do suporte ao modelo Multi-Tenant, e

das demais classes necessárias para compor a solução.

Page 14: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 14/23

Para começar, 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 necessário implementá-la, definindo seus atributos, métodos

“acessores” e mapeando-a com anotações, conforme realizado na Listagem 5. E válido

lembrar também de mapeá-la no arquivo persistence.xml, para que a unidade de

persistência consiga gerenciá-la.

Listagem 5. Implementação 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 representação na base de dados

@Entity(name = "Pessoa")

public class Pessoa implements Serializable {

private static final long serialVersionUID = 1L;

//Definição de atributo identificador

@Id

private Long id;

private String nome;

// Métodos get/set omitidos

}

Após realizar a implementação da classe Pessoa, é preciso criar um arquivo XML de

configurações para o Hibernate. Este arquivo é similar ao persitence.xml quanto a

finalidade, variando apenas na sintaxe e possuindo alguns recursos extras de

configuração específicos do Hibernate. O arquivo dever ser criado na pasta src e

nomeado como hibernate.cfg.xml. O corpo deste arquivo pode ser visto na Listagem 6.

Listagem 6. Arquivo de configurações do Hibernate – hibernate.cfg.xml.

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<property name="hibernate.ejb.naming_strategy">

org.hibernate.cfg.ImprovedNamingStrategy"</property>

<property name="hibernate.connection.driver_class">

Page 15: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 15/23

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>

Neste arquivo existem duas propriedades que são extremamente importantes, pois são

elas que determinam o modelo de abordagem Multi-Tenancy que será utilizada pela

aplicação. A primeira é a hibernate.multiTenancy, que é responsável por definir que o

modelo que será utilizado será baseado em um esquema exclusivo por cliente, e a outra

propriedade é a hibernate.multi_tenant_connection_provider, que define qual será a

classe responsável por obter as conexões de acordo com o identificador do cliente. As

demais propriedades devem ser configuradas de acordo com a base de dados utilizada,

com as classes de modelo que estarão passiveis de persistência, e outras preferências do

desenvolvedor.

Tendo configurado o arquivo XML com as propriedades do Hibernate, realiza-se então a

criação das demais classes que compõem o projeto. Estas classes são responsáveis por

utilizar efetivamente o recurso de Multi-Tenancy baseado no esquema exclusivo por

cliente.

A Listagem 7 apresenta a classe ConnectionProviderBuilder com alguns comentários

sobre algumas das suas características. Ela disponibiliza dois métodos que, em conjunto,

são responsáveis por fornecer conexões configuradas para o SGBD escolhido. O método

Page 16: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 16/23

getConnectionProviderProperties(), por exemplo, se encarregará de construir e

devolver um arquivo de propriedades com todos os parâmetros necessários para

estabelecer tais conexões, enquanto o método buildConnectionProvider() utilizará

este recurso para criar uma instância da classe

DriverManagerConnectionProviderImpl, que tem como papel fornecer conexões

valendo-se dos recursos da classe DriverManager.

Listagem 7. Classe construtora de provedores de conexões –

ConnectionProviderBuilder.

package br.edu.utfpr.application;

import java.util.Properties;

import org.hibernate.cfg.Environment;

import org.hibernate.service.jdbc.connections.internal

.DriverManagerConnectionProviderImpl;

//Classe responsável por prover conexão com o banco de dados a partir de

//configurações e propriedades

public class ConnectionProviderBuilder {

//Constantes utilizadas para configuração da conexão 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;

Page 17: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 17/23

}

};

connectionProvider.configure(props);

return connectionProvider;

}

}

Concluída a implementação de ConnectionProviderBuilder, deve-se criar uma nova

classe para que seja possível obter conexões baseadas em identificadores. Seu nome,

acompanhado de sua localização no projeto, devem ser atribuídos à propriedade

hibernate.multi_tenant_connection_provider, definida no XML de configurações do

Hibernate.

Esta nova classe, em nosso exemplo, receberá o nome de

MultiTenantConnectionProviderImpl, e será responsável por prover conexões de

acordo com o identificador do inquilino, sendo esta uma das características essenciais na

implementação do modelo arquitetural Multi-Tenant. Para que isso seja possível o

Hibernate fornece a interface MultiTenantConnectionProvider, que define uma série de

métodos necessários para obtenção e liberação do acesso à fonte de dados e que devem

ser implementados. Detalhes de sua implementação estão apresentados na Listagem 8.

Listagem 8. Classe provedora de conexões baseadas em identificadores –

MultiTenantConnectionProviderImpl.

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 responsável por prover conexões baseadas nos identificadores

// dos clientes

public class MultiTenantConnectionProviderImpl implements

MultiTenantConnectionProvider {

//Definição da instância da classe construtora de provedores de conexão

private final ConnectionProvider connectionProvider =

ConnectionProviderBuilder

.buildConnectionProvider("cliente1");

Page 18: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 18/23

//Método que permite o acesso à base de dados em situações onde não há

//identificadores para os clientes

@Override

public Connection getAnyConnection() throws SQLException {

return connectionProvider.getConnection();

}

//Método de libera uma conexão obtida através do método

// getAnyConnection()

@Override

public void releaseAnyConnection(Connection connection)

throws SQLException {

connectionProvider.closeConnection(connection);

}

//Método que obtém uma conexão de acordo com o identificador do cliente

//(esquema)

@Override

public Connection getConnection(String tenantIdentifier)

throws SQLException {

final Connection connection = getAnyConnection();

try {

connection.createStatement().execute("USE " +

tenantIdentifier);

} catch (SQLException e) {

throw new HibernateException(

"Não pode alterar a conexão para o esquema especificado ["

+ tenantIdentifier + "]", e);

}

return connection;

}

//Método que libera uma conexão obtida através do método

// getConnection()

@Override

public void releaseConnection(String tenantIdentifier,

Connection connection)

throws SQLException {

try {

connection.createStatement().execute("USE " +

tenantIdentifier);

} catch (SQLException e) {

throw new HibernateException(

" Não pode alterar a conexão para o esquema especificado ["

+ tenantIdentifier + "]", e);

}

connectionProvider.closeConnection(connection);

Page 19: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 19/23

}

//Métodos não 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, propõe-se a criação de uma classe para inserir alguns registros na base de

dados, apenas para demonstrar o uso da funcionalidade de Multi-Tenancy. A

implementação desta visa obter sessões de acordo com o inquilino desejado e realizar

inserções utilizando a sessão adquirida. A Listagem 9 apresenta o código dessa classe.

Um detalhe importante nesta classe é a definição do método

configureSessionFactory(), que segue o novo modelo definido pelo Hibernate para

obtenção de uma SessionFactory. Seu funcionamento baseia-se essencialmente na

utilização do arquivo XML de propriedades para configurar novas fábricas de sessão.

Listagem 9. Código 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 {

// Fábrica de sessões

private static SessionFactory sessionFactory;

Page 20: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 20/23

public static void main(String[] args) {

sessionFactory = configureSessionFactory();

//Obtenção de sessão através do identificador do cliente1

Session session = sessionFactory.withOptions()

.tenantIdentifier("cliente1").openSession();

session.beginTransaction();

Pessoa pessoa = new Pessoa();

pessoa.setId(1L);

pessoa.setNome("Tenant One");

session.save(pessoa);

session.getTransaction().commit();

//Encerrando sessão do cliente1

session.close();

//Obtenção de sessão através do identificador do cliente2

session = sessionFactory.withOptions().tenantIdentifier("cliente2")

.openSession();

session.beginTransaction();

Pessoa pessoa2 = new Pessoa();

pessoa2.setId(1L);

pessoa2.setNome("Tenant Two");

session.save(pessoa2);

session.getTransaction().commit();

//Encerrando sessão do cliente2

session.close();

}

// Método que realiza as configurações da fábrica de sessões

private static SessionFactory configureSessionFactory()

throws HibernateException {

Configuration configuration = new Configuration().configure();

ServiceRegistryBuilder serviceRegistryBuilder =

new ServiceRegistryBuilder();

serviceRegistryBuilder.applySettings

(configuration.getProperties());

ServiceRegistry serviceRegistry =

serviceRegistryBuilder.buildServiceRegistry();

sessionFactory = configuration.buildSessionFactory

(serviceRegistry);

return sessionFactory;

}

Page 21: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 21/23

}

A Listagem 10 apresenta o resultado obtido após a execução da classe de testes

MultiTenancyEsquemaExclusivo. Esse resultado demonstra que o processo de

inserção seguiu a definição do cliente, conforme os parâmetros utilizados na obtenção de

novas sessões, e que os dados foram armazenados de acordo com a separação por

esquema.

Listagem 10. Resultado da execução da aplicação.

Mar 10, 2013 3:53:07 AM org.hibernate.tool.hbm2ddl.SchemaExport execute

INFO: HHH000230: Schema export complete

Hibernate:

insert

into

Pessoa

(nome, id)

values

(?, ?)

Hibernate:

insert

into

Pessoa

(nome, id)

values

(?, ?)

A Listagem 11 apresenta duas consultas feitas nas tabelas para checar os resultados

das inserções. Como pode ser visto a partir dos registros retornados, as ações de

inserção foram bem sucedidas.

Listagem 11. Resultado das consultas realizadas nas tabelas de cada cliente.

mysql> USE cliente1;

mysql> SELECT * FROM Pessoa;

+----+------------+

| id | nome |

+----+------------+

| 1 + Tenant One |

Page 22: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 22/23

+----+------------+

mysql> USE cliente2;

mysql> SELECT * FROM Pessoa;

+----+------------+

| id | nome |

+----+------------+

| 1 + Tenant Two |

+----+------------+

Conclusão

Este artigo apresentou as opções de suporte que o framework Hibernate, na versão 4,

oferece ao modelo arquitetural Multi-Tenant. Foram descritas algumas das características

presentes na nova versão da ferramenta e um dos recursos adicionados foi trabalhado

em um exemplo prático.

Além de expor variações do modelo Multi-Tenant, foi construída uma aplicação a fim de

exemplificar a atuação 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 solução em um dos possíveis

modelos de arquitetura, porém, cabe ao arquiteto do sistema optar pela opção que

melhor se ajusta às necessidades do projeto, levando em consideração os fatores

positivos e negativos relacionados à sua adoção.

Dentre as principais vantagens associadas ao emprego de uma solução Multi-Tenant,

destacam-se a significativa redução de custos com recursos físicos, devido ao

compartilhamento e reutilização 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 necessários para cada novo cliente, garantindo que os demais inquilinos não

sofram influência negativa desta inclusão, e o risco associado a uma possível falha nos

recursos de uso compartilhado, que pode acabar afetando vários clientes e ocasionar

uma perda de grandes volumes de dados.

Page 23: Introdução a Multi-Tenancy Com Hibernate 4

29/7/2014 Introdução a Multi-Tenancy com Hibernate 4

http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29114 23/23

Links

Hibernate – Community Documentation – Multi-Tenancy

http://docs.jboss.org/hibernate/core/4.1/devguide/en-US/html/ch16.html

Hibernate 4: multitenancy, extensões, OSGI e uma entrevista com o líder 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

DevMedia - Equipe De Moderação

A DevMedia é um portal para analistas, desenvolvedores de sistemas, gerentes e DBAs com milhares de

artigos, dicas, cursos e videoaulas gratuitos e exclusivos para assinantes.