Sei sulla pagina 1di 78

Curso

Hibernate

1
Curso
Hibernate

1. CONCEITOS GERAIS DE PERSISTNCIA 4

2. MAPEAMENTO OBJETO RELACIONAL 4

2.1 MAPEAMENTO OBJETO RELACIONAL

2.1.1 Mapeamento de um objeto com tipos primitivos

2.1.2 Mapeamento de objetos que contm uma coleo de objetos

3. INTRODUO AO HIBERNATE 8

4. ARQUITETURA 8

4.1 SESSION (ORG.HIBERNATE.SESSION)

4.2 SESSIONFACTORY (ORG.HIBERNATE.SESSIONFACTORY)

4.3 CONFIGURATION (ORG..HIBERNATE.CONFIGURATION)

4.4 TRANSACTION (ORG.HIBERNATE.TRANSACTION)

4.5 INTERFACES CRITERIA E QUERY

5. CLASSES PERSISTENTES 10

5.1 IDENTIDADE/IGUALDADE ENTRE OBJETOS

5.2 ESCOLHENDO CHAVES PRIMRIAS

6. OBJETOS PERSISTENTES, TRANSIENTES E DETACHED 14

7. INTRODUO A ANOTAES (ANNOTATIONS) 15

7.1 TIPOS DE ANOTAES SUPORTADAS PELO JAVA 5.0

8. CONFIGURANDO O HIBERNATE 19

9. MANIPULANDO OBJETOS PERSISTENTES 21

10. MAPEANDO ATRIBUTOS DA CLASSE 24

11. ASSOCIAES 27

11.1 ASSOCIAES 1-N (ONE-TO-MANY)

11.2 ASSOCIAES N-1 (MANY-TO-ONE)

11.3 ASSOCIAES N-N (MANY-TO-MANY)

2
Curso
Hibernate

11.4 ASSOCIAES N-N COM ATRIBUTOS

11.4.1 Composite-id

11.5 ASSOCIAES 1-1 (ONE-TO-ONE)

12. DEFINIO DE CHAVE PRIMRIA 48

13. COLEES 49

13.1 SET

13.2 LIST

13.3 MAP

13.4 MAP

14. TRANSAES 56

14.1 MODELOS DE TRANSAES

14.2 TRANSAES E BANCO DE DADOS

14.3 AMBIENTES GERENCIADOS E NO GERENCIADOS

14.4 TRANSAES JDBC

14.5 TRANSAES JTA

14.6 API PARA TRANSAES DO HIBERNATE

14.7 FLUSHING

14.8 NVEIS DE ISOLAMENTO DE UMA TRANSAO

14.9 CONFIGURANDO O NVEL DE ISOLAMENTO

15. CONCORRNCIA 66

15.1 LOCK OTIMISTA

15.2 LOCK PESSIMISTA

16. CACHING 74

16.1 ARQUITETURA DE CACHE COM HIBERNATE

16.2 MAPEANDO CACHE

3
Curso
Hibernate

1. CONCEITOS GERAIS DE PERSISTNCIA

Quando se fala em persistncia de dados logo nos vem a mente


modelos complexos e cheios de abreviaes: DAO, ORM, Integridade
Relacional. A verdade reside no fato de que esses conceitos so
imprescindveis para construo de uma aplicao robusta, mas a
interao do desenvolvedor com eles pode ser muito amigvel com a
utilizao do framework Hibernate.

A codificao de camadas de persistncia so meticulosas e a demanda


de tempo e possibilidades de erros so tpicos de teor conclusivo para
este trabalho. Contudo, mais do que abordar caractersticas e,
principalmente, a simplicidade desse framework, o ponto alto de toda
argumentao est no entendimento da mudana de paradigma
proporcionada pelo Hibernate no trabalho com banco de dados, ou
seja, o trabalho estruturada sobreposto pelo orientada objeto, o
que torna essa ferramenta atrativa pela maximizao da produtividade.

O uso do Hibernate torna a aplicao malevel a mais de um tipo de


banco de dados, isso depende, na maioria das vezes, apenas de
poucos minutos de uma reconfigurao bsica do framework. Ele
tambm deixa transparente as operaes CRUD de dados. Contudo o
principal ponto de destaque est no paradigma de OO para banco de
dados, tornando a modelagem e o trabalho de programao muito
mais elagante.

2. MAPEAMENTO OBJETO RELACIONAL

Por vrios anos os projetos de aplicaes corporativas tiveram uma


forte necessidade de se otimizar a comunicao da lgica de negcio
com a base de dados. Essa necessidade ganhou mais intensidade com
o crescimento dessas aplicaes, crescimento esse, tanto em requisitos
(funcionalidade) quanto em volume de dados armazenados em seu
banco de dados.

4
Curso
Hibernate

Na dcada de 80, foram criados os bancos de dados relacionais (BDR)


que substituram as bases de dados de arquivos. Para esse tipo de
base de dados foi criada uma linguagem, a SQL. Essa linguagem foi
toda baseada na lgica relacional e por isso contava com diversas
otimizaes em suas tarefas se comparadas com as outras tecnologias
existentes. A partir de ento foi diminudo o tempo gasto para as
operaes de persistncia, mesmo com um grande volume de dados.
Entretanto, essa linguagem no propiciava aos desenvolvedores uma
facilidade para que a produtividade fosse aumentada.

Uma soluo que surgiu no incio da dcada de 90 foi criao de um


modelo de banco de dados baseado no conceito de orientao a
objetos. Este modelo visava facilitar, para os desenvolvedores, a
implementao da camada de persistncia da aplicao, pois eles j
estavam familiarizados com o paradigma de orientao a objetos,
conseqentemente, a produtividade certamente aumentaria.

Na prtica, esse modelo de dados no foi utilizado em grandes


aplicaes, isto que elas tinham um volume de dados muito grande e
esse modelo era ineficiente em termos de tempo de resposta, pois ao
contrrio dos bancos de dados relacionais, eles no tinham um modelo
matemtico que facilitasse as suas operaes de persistncias.

Ento a soluo foi usar os BDR e desenvolver ferramentas para que o


seu uso seja facilitado. Uma dessas ferramentas o framework
Hibernate que usa o conceito de mapeamento objeto relacional (MOR).

2.1 M APEAMENTO OBJETO RELACIONAL

Como foi descrito anteriormente, mapeamento objeto relacional


funciona com a transformao dos dados de um objeto em uma
linha de uma tabela de um banco de dados, ou de forma
inversa, com a transformao de uma linha da tabela em um
objeto da aplicao. Abordando essa idia, alguns problemas
podero existir, como, se um objeto tiver uma coleo de outros
objetos.

2.1.1 Mapeamento de um objeto com tipos primitivos

Esse o mapeamento mais simples, onde um objeto tem apenas tipos


de dados bsicos. Vale salientar que entendesse por tipos bsicos
aqueles que possuem um correspondente em SQL, ou seja, o tipo
String da linguagem Java considerado um tipo bsico, pois ele possui

5
Curso
Hibernate

um correspondente em SQL.

Na Figura 1, observa-se o mapeamento de trs objetos do tipo Veiculo


na tabela de um banco de dados. Caso a aplicao deseje saber o
veculo da cor vermelha, por exemplo, ento o objeto que tem o Plio
como modelo retornado.

Figura 1 - Exemplo de mapeamento de tipos bsicos

2.1.2 Mapeamento de objetos que contm uma coleo de


objetos

Esse tipo de mapeamento quando um objeto possui um conjunto de


outros objetos. Para obter esse conceito necessrio adicionar, ao
exemplo da Figura 1, uma nova classe chamada de Fabricante que
conter as informaes: nome, que armazenar o nome desse
fabricante e o veiculos, que conter o conjunto de veculos do
fabricante (telefone e endereco no so informaes relevantes no
exemplo). Faz-se necessrio a adio de uma informao na classe
Veiculo chamada de fabricante, como mostrado na Figura 2.

Figura 2 - Relacionamento entre as classes Fabricante e Veiculo

6
Curso
Hibernate

O atributo fabricante adicionado em Veiculo simplesmente para


relacionar um veculo ao seu fabricante, enquanto o veiculos de
Fabricante referencia a classe Veiculo.

Como foram realizadas mudanas no domnio do exemplo orientado a


objetos, faz-se necessria uma alterao no modelo do banco de
dados. Primeiramente, o vnculo que foi realizado entre um fabricante
e um veculo dever ser implementado atravs de uma chave
estrangeira (referncia a uma outra tabela, pois em BDR no existe o
conceito de colees) que se localizar na tabela VEICULO,
caracterizando o mapeamento 1 para N, ou seja, um veculo possui
apenas um fabricante e um fabricante possui vrios (N) veculos. Essa
chave estrangeira ser realizada entre a informao nome da classe
Fabricante e o atributo fabricante da classe Veiculo.

Figura 3 Exemplo de mapeamento 1 para N

Para um melhor entendimento, a Figura 3 mostra o mapeamento dos


objetos para as tabelas no BDR. Nele observa-se que cada veculo
est associado com um fabricante, isso implica dizer que na tabela de
VEICULO existe uma referncia para a tabela FABRICANTE. Essa
associao feita atravs da coluna fabricante da tabela VEICULO.
Pensando em termos prticos, quando um veculo for inserido no
banco de dados, ele ser ligado ao seu respectivo fabricante, no
momento da insero.

Para recuperar os veculos inseridos o desenvolvedor ter que


implementar uma busca que retorne alm das informaes do veculo
as informaes do seu fabricante, isso poder ser realizado fazendo a
seguinte consulta SQL: SELECT * FROM fabricante WHERE nome =
<fabricante>, onde <fabricante> o nome do fabricante que est na
tabela VEICULO, por exemplo, caso a aplicao deseje as informaes
do veculo do modelo Plio, ento para se buscar o fabricante a

7
Curso
Hibernate

seguinte consulta ser realizada: SELECT * FROM fabricante WHERE


nome = 'Fiat'.

Utilizando a mesma idia, os fabricantes so buscados; a nica


diferena que agora a consulta que buscar os veculos associados
com o fabricante retornar uma coleo de veculos (SELECT * FROM
veiculo WHERE fabricante = <nomeFabricante>). Esse tipo de
mapeamento muito utilizado em aplicaes em que os objetos
fazem muita referncia a outros objetos.

Com a idia do MOR vrios projetos de ferramenta comearam a ser


desenvolvidas, visando facilitar a implementao da camada de
persistncia, dentre elas o framework Hibernate, que um software
livre de cdigo aberto e que est tendo uma forte adeso de novos
projetos corporativos.

3. INTRODUO AO HIBERNATE

O Hibernate um framework de mapeamento objeto relacional para


aplicaes Java, ou seja, uma ferramenta para mapear classes Java
em tabelas do banco de dados e vice-versa. bastante poderoso e d
suporte ao mapeamento de associaes entre objetos, herana,
polimorfismo, composio e colees.

O Hibernate no apresenta apenas a funo de realizar o mapeamento


objeto relacional. Tambm disponibiliza um poderoso mecanismo de
consulta de dados, permitindo uma reduo considervel no tempo de
desenvolvimento da aplicao.

4. ARQUITETURA

A arquitetura do Hibernate formada basicamente por um conjunto de


interfaces. A Figura 4 apresenta as interfaces mais importantes nas
camadas de negcio e persistncia. A camada de negcio aparece
acima da camada de persistncia por atuar como uma cliente da
camada de persistncia. Vale salientar que algumas aplicaes podem
no ter a separao clara entre as camadas de negcio e de
persistncia.

De acordo com a Figura 4, as interfaces so classificadas como:

8
Curso
Hibernate

Interfaces responsveis por executar operaes de criao,


deleo, consulta e atualizao no banco de dados: Session,
Transaction e Query;

Interface utilizada pela aplicao para configurar o Hibernate:


Configuration;

Interfaces responsveis por realizar a interao entre os eventos


do Hibernate e a aplicao: Interceptor, Lifecycle e Validatable.

Interfaces que permitem a extenso das funcionalidades de


mapeamento do Hibernate: UserType, CompositeUserType,
IdentifierGenerator.

O Hibernate tambm interage com APIs j existentes do Java: JTA,


JNDI e JDBC.

Figura 4 - Arquitetura do Hibernate

4.1 SESSION (ORG.HIBERNATE.SESSION)

9
Curso
Hibernate

O objeto Session aquele que possibilita a comunicao entre a


aplicao e a persistncia, atravs de uma conexo JDBC. um objeto
leve de ser criado, no deve ter tempo de vida por toda a aplicao e
no threadsafe. Um objeto Session possui um cache local de objetos
recuperados na sesso. Com ele possvel criar, remover, atualizar e
recuperar objetos persistentes.

4.2 SESSIONFACTORY (ORG.HIBERNATE.SESSIONFACTORY)

O objeto SessionFactory aquele que mantm o mapeamento objeto


relacional em memria. Permite a criao de objetos Session, a partir
dos quais os dados so acessados, tambm denominado como fbrica
de objetos Sessions.

Um objeto SessionFactory threadsafe, porm deve existir apenas


uma instncia dele na aplicao, pois um objeto muito pesado para
ser criado vrias vezes.

4.3 CONFIGURATION (ORG..HIBERNATE.CONFIGURATION)

Um objeto Configuration utilizado para realizar as configuraes de


inicializao do Hibernate. Com ele, define-se diversas configuraes
do Hibernate, como por exemplo: o driver do banco de dados a ser
utilizado, o dialeto, o usurio e senha do banco, entre outras. a partir
de uma instncia desse objeto que se indica como os mapeamentos
entre classes e tabelas de banco de dados devem ser feitos.

4.4 TRANSACTION (ORG.HIBERNATE.TRANSACTION)

A interface Transaction utilizada para representar uma unidade


indivisvel de uma operao de manipulao de dados. O uso dessa
interface em aplicaes que usam Hibernate opcional. Essa interface
abstrai a aplicao dos detalhes das transaes JDBC, JTA ou CORBA.

4.5 INTERFACES CRITERIA E QUERY

As interfaces Criteria e Query so utilizadas para realizar consultas ao


banco de dados.

5. CLASSES PERSISTENTES

As classes persistentes de uma aplicao so aquelas que

10
Curso
Hibernate

implementam as entidades de domnio de negcio. O Hibernate


trabalha associando cada tabela do banco de dados a um POJO (Plain
Old Java Object). POJOs so objetos Java que seguem a estrutura de
JavaBeans (construtor padro sem argumentos, e mtodos getters e
setters para seus atributos). A Listagem 1 apresenta a classe Pessoa
representando uma classe POJO.

Listagem 1 Exemplo de Classe POJO

Consideraes:

O Hibernate requer que toda classe persistente possua um


construtor padro sem argumentos, assim, o Hibernate
pode instanci-las simplesmente chamando
Construtor.newInstance();

Observe que a classe Pessoa apresenta mtodos setters e


getters para acessar ou retornar todos os seus atributos. O
Hibernate persiste as propriedades no estilo JavaBeans,
utilizando esses mtodos;

11
Curso
Hibernate

A classe Pessoa possui um atributo id que o seu


identificador nico. importante que, ao utilizar Hibernate,
todos os objetos persistentes possuam um identificador e
que eles sejam independentes da lgica de negcio da
aplicao.

5.1 IDENTIDADE/IGUALDADE ENTRE OBJETOS

Em aplicaes Java, a identidade entre objetos pode ser obtida


a partir do operador ==. Por exemplo, para verificar se dois
objetos obj1 e obj2 possuem a mesma identidade Java, basta
verificar se obj1 == obj2. Dessa forma, dois objetos possuiro
a mesma identidade Java se ocuparem a mesma posio de
memria.

O conceito de igualdade entre objetos diferente. Dois objetos,


por exemplo, duas Strings, podem ter o mesmo contedo, mas
verificar se as duas so iguais utilizando o operador ==, pode
retornar um resultado errado, pois como j citado, o operado
== implicar em uma verificao da posio de memria e no
do contedo. Assim, para verificar se dois objetos so iguais
em Java, deve-se utilizar o mtodo equals, ou seja, verificar se
obj1.equals(obj2).

Incluindo o conceito de persistncia, passa a existir um novo


conceito de identidade, a identidade de banco de dados. Dois
objetos armazenados em um banco de dados so idnticos se
forem mapeados em uma mesma linha da tabela.

5.2 ESCOLHENDO CHAVES PRIMRIAS

Um passo importante ao utilizar o Hibernate inform-lo sobre


a estratgia utilizada para a gerao de chaves primrias.

Uma chave candidata uma coluna ou um conjunto de


colunas que identifica unicamente uma linha de uma tabela do
banco de dados. Ela deve satisfazer as seguintes propriedades:

nica;

Nunca ser nula;

Constante.

12
Curso
Hibernate

Uma nica tabela pode ter vrias colunas ou combinaes de


colunas que satisfazem essas propriedades. Se a tabela possui
um nico atributo que a identifique, ele por definio a sua
chave primria. Se possuir vrias chaves candidatas, uma deve
ser escolhida para representar a chave primria e as demais
serem definidas como chaves nicas.

Muitas aplicaes utilizam como chaves primrias chaves


naturais, ou seja, que tm significados de negcio. Por
exemplo, o atributo cpf da tabela Pessoa (associada classe
Pessoa). Essa estratgia pode no ser muito boa em longo
prazo, j que uma chave primria adequada deve ser
constante, nica e no nula. Dessa forma, se for desejado que
a chave primria da tabela Pessoa seja uma outra ao invs do
cpf, podem surgir problemas j que provavelmente o cpf deve
ser referenciado em outras tabelas. Um problema que poderia
acontecer seria a remoo do cpf da tabela.

O Hibernate apresenta vrios mecanismos internos para a


gerao de chaves primrias. Veja a Tabela 1.

Tabela 1 - Mecanismo de Gerao de Chaves Primrias

Mecanismo Descrio

Identity Mapeado para colunas identity no DB2,


MySQL, MSSQL, Sybase,
HSQLDM, Infomix.

Sequence Mapeado em seqncias no DB2,


PostgreSQL, Oracle, SAP DB,
Firebird (ou generator no Interbase).

Increment L o valor mximo da chave primria e


incrementa um. Deve ser
usado quando a aplicao a nica a
acessar o banco e de
forma no concorrente.

Hilo Usa algoritmo high/low para gerao de


chaves nicas.

uudi.hex Usa uma combinao do IP com um


timestamp para gerar um
identificador nico na rede.

13
Curso
Hibernate

6. OBJETOS PERSISTENTES, TRANSIENTES E DETACHED

Nas diversas aplicaes existentes, sempre que for necessrio


propagar o estado de um objeto que est em memria para o banco de
dados ou vice-versa, h a necessidade de que a aplicao interaja com
uma camada de persistncia. Isto feito, invocando o gerenciador de
persistncia e as interfaces de consultas do Hibernate. Quando
interagindo com o mecanismo de persistncia, necessrio para a
aplicao ter conhecimento sobre os estados do ciclo de vida da
persistncia.

Em aplicaes orientadas a objetos, a persistncia permite que um


objeto continue a existir mesmo aps a destruio do processo que o
criou. Na verdade, o que continua a existir seu estado, j que pode
ser armazenado em disco e ento, no futuro, ser recriado em um novo
objeto.

Em uma aplicao no h somente objetos persistentes, pode haver


tambm objetos transientes. Objetos transientes so aqueles que
possuem um ciclo de vida limitado ao tempo de vida do processo que o
instanciou. Em relao s classes persistentes, nem todas as suas
instncias possuem necessariamente um estado persistente. Elas
tambm podem ter um estado transiente ou detached.

O Hibernate define estes trs tipos de estados: persistentes,


transientes e detached. Objetos com esses estados so definidos como
a seguir:

Objetos Transientes: so objetos que suas instncias no


esto nem estiveram associados a algum contexto
persistente. Eles so instanciados, utilizados e aps a sua
destruio no podem ser reconstrudos automaticamente;

Objetos Persistentes: so objetos que suas instncias esto


associadas a um contexto persistente, ou seja, tem uma
identidade de banco de dados.

Objetos detached: so objetos que tiveram suas instncias


associadas a um contexto persistente, mas que por algum
motivo deixaram de ser associadas, por exemplo, por
fechamento de sesso, finalizao de sesso. So objetos
em um estado intermedirio, nem so transientes nem
persistentes.

14
Curso
Hibernate

O ciclo de vida de um objeto persistente pode ser resumido a partir


da Figura 5.

Figura 5: Ciclo de Vida - Persistncia

De acordo com a figura acima, inicialmente, o objeto pode ser criado


e ter o estado transiente ou persistente. Um objeto em estado
transiente se torna persistente se for criado ou atualizado no banco
de dados. J um objeto em estado persistente, pode retornar ao
estado transiente se for apagado do banco de dados. Tambm pode
passar ao estado detached, se, por exemplo, a sesso com o banco
de dados por fechada. Um objeto no estado detached pode voltar ao
estado persistente se, por exemplo, for atualizado no banco de
dados. Tanto do estado detached quanto do estado transiente o
objeto pode ser coletado para destruio.

7. INTRODUO A ANOTAES (ANNOTATIONS)

Para utilizar o Hibernate Annotation, primeiramente, preciso copiar


sua verso atual do site http://hibernate.org, disponvel em um
arquivo compactado. Ento, este arquivo deve ser descompactado e

15
Curso
Hibernate

seu contedo consiste em um conjunto de arquivos JARs. Esses


arquivos devem ser copiados para o diretrio das libs de sua aplicao.
Os arquivos hibernate- annotations.jar e lib/ejb3-persistence.jar
tambm devem referenciados no classpath da aplicao, juntamente
com a classe do driver do banco de dados utilizado.

Como j citado, o mapeamento objeto relacional utilizando Hibernate


pode ser feito a partir de anotaes. As anotaes podem ser definidas
como metadados que aparecem no cdigo fonte e so ignorados pelo
compilador. Qualquer smbolo em um cdigo Java que comece com
uma @ (arroba) uma anotao. Este recurso foi introduzido na
linguagem Java a partir da verso Java SE 5.0. Em outras palavras, as
anotaes marcam partes de objetos de forma que tenham algum
significado especial.

A Listagem 2 e a Listagem 3 apresentam exemplo de um tipo de


anotao denominado de TesteAnotacao e do seu uso em um mtodo
qualquer (metodoTeste), respectivamente. O exemplo meramente
ilustrativo, de forma que o tipo de anotao definido no agrega
nenhum significado especial ao cdigo fonte.

Listagem 2 Exemplo ilustrativo para a criao de um tipo de anotao

Listagem 3 Exemplo ilustrativo para o uso de um tipo de anotao

As anotaes podem possuir nenhum, um ou mais de um elementos


em sua definio. Um exemplo de tipo de anotao sem nenhum
atributo j foi visto nas Listagem 2 e na Listagem 3. Se um tipo de
anotao possui um nico elemento, como definido e ilustrado na
Listagem 4, no momento de se utilizar a anotao, um valor para este
atributo deve ser passo entre parnteses, como mostrado na Listagem
5

16
Curso
Hibernate

Listagem 4 Exemplo ilustrativo para a criao de um tipo de anotao

Listagem 5 Exemplo ilustrativo para o uso de um tipo de. Anotao

No caso em que o tipo da anotao ser definido com mais de um


elemento, como mostrado na Listagem 6, na hora em que a anotao
for usada, para atribuir valores para seus elementos preciso pass-
los tambm entre parnteses, porm definindo o nome do elemento e
o seu valor, como exemplo ilustrado na Listagem 7.

Listagem 6 Exemplo ilustrativo para a criao de um tipo de anotao

Listagem 7 Exemplo ilustrativo para o uso de um tipo de anotao

7.1 TIPOS DE ANOTAES SUPORTADAS PELO JAVA 5.0

Dois tipos de anotaes so suportadas pelo Java 5.0: anotaes


simples e meta anotaes. As anotaes simples so usadas apenas
para agregar significado especial ao cdigo fonte, mas no para criar
algum tipo de anotao. J as meta anotaes so aquelas utilizadas
para definir tipos de anotaes.

No o intuito desta seo detalhar cada um dos tipos de anotaes


existentes no Java 5.0, mas apenas cit-las e apresentar os seus
significados.

17
Curso
Hibernate

As anotaes simples do Java 5.0 so trs:

@Override: indica que o mtodo que possui esta anotao


deve ter a sua implementao sobrescrevendo a de sua
superclasse. Se o mtodo anotado no tiver implementao, o
compilador gerar um erro;

@Deprecated: permite indicar que algum elemento do cdigo


fonte est em desuso, ou com uso depreciado. A anotao
servir para que o compilador alerte o programador quanto
utilizao de um elemento em desuso;

@Suppresswarnings: esta anotao indica ao compilador que


os alertas (warnings) no elemento anotado no sejam
informados ao programador.

J as meta anotaes so:

@Target: indica em que nvel dos elementos da classe a


anotao ser aplicada, por exemplo: a qualquer tipo; a um
atributo, a um mtodo, a um construtor, etc;

@Retention: indica onde e quanto tempo a anotao ser


considerada. Por exemplo: se apenas a nvel de cdigo fonte e
ignoradas pelo compilador; se apenas pelo compilador em
tempo de compilao e no pela JVM; ou consideradas pela
JVM apenas em tempo de execuo;

@Documented: indica que o elemento anotado deve ser


documentado atravs de alguma ferramenta javadoc;

@Inherited: indica que a classe anotada com este tipo


automaticamente herdada. Por exemplo, se uma anotao
definida a partir de @Inherited, uma classe anotada por esta
nova anotao ir herdar automaticamente todos os seus
elementos.

Mais informaes sobre estes tipos de anotaes a partir do artigo An


Introduction to Java Annotation por M. M. Islam Chisty (Outrubro,
2005).

Inicialmente, o mapeamento objeto relacional com Hibernate era feito


a partir de um conjunto de configuraes em arquivos XMLs. Com o
surgimento das anotaes no Java SE 5.0, o framework Hibernate
anexou este recurso, permitindo que as classes Java fossem mapeadas
a partir de anotaes, simplificando o seu uso. A prxima seo

18
Curso
Hibernate

apresentar um exemplo simples do uso da persistncia de uma classe


com Hibernate Annotations.

8. CONFIGURANDO O HIBERNATE

Pode-se configurar o Hibernate de trs maneiras distintas:

Instanciar um objeto de configurao


(org.hibernate.cfg.Configuration) e inserir suas
propriedades programaticamente;

Usar um arquivo .properties com as suas configuraes e


indicar as classes mapeadas programaticamente;

Usar um arquivo XML (hibernate.cfg.xml) com as


propriedades de inicializao e os caminhos das classes
mapeadas.

Ser apresentada a configurao a partir do arquivo


hibernate.cfg.xml.

Um exemplo deste arquivo de configurao pode ser visto na


Listagem 11. Vrios parmetros podem ser configurados.
Basicamente, deve-se configurar:

A URL de conexo com o banco de dados;

Usurio e senha do banco de dados;

Nmeros mximo e mnimo de conexes no pool;

Dialeto.

19
Curso
Hibernate

Listagem 11 - Arquivo de Configurao hibernate.cfg.xml

Resumindo as descries das propriedades a serem configuradas:

hibernate.dialect: implementao do dialeto SQL especfico


do banco de dados a ser utilizado. Usado para identificar as
particularidades do banco de dados;

hibernate.connection.driver_class: nome da classe do driver


JDBC do banco de dados que est sendo utilizado;

hibernate.connection.url: a URL de conexo especfica do


banco que est sendo utilizado;

hibernate.connection.username: o nome de usurio com o


qual o Hibernate deve se conectar ao banco;

hibernate.connection.password: a senha do usurio com o


qual o Hibernate deve se conectar ao banco;

hibernate.connection.pool_size: tamanho do pool de


conexes;

hibernate.connection.isolation: define o nvel de isolamento.


Parmetro opcional;

hibernate.show_sql: utilizado para definir se os SQL s


gerados pelo Hibernate devem ou no ser exibidos (true |
false).

20
Curso
Hibernate

O Hibernate trabalha com dialetos para um grande nmero de bancos


de dados, tais como: DB2, MySQL, Oracle, Sybase, Progress,
PostgreSQL, Microsoft SQL Server, Ingres, Informix entre outros.
Possveis valores para os dilates esto presentes na Tabela 2.

Tabela 2 - Possveis valores de dialetos

J no final do arquivo hibernate.cfg.xml onde devem ser informados


os arquivos das classes mapeadas que o Hibernate deve processar.
Se alguma classe no for definida neste local, a mesma no poder
ser persistida utilizando os mecanismos do Hibernate.

9. MANIPULANDO OBJETOS PERSISTENTES

O Hibernate utiliza objetos Session para persistir e recuperar objetos.


Um objeto Session pode ser considerado como uma sesso de
comunicao com o banco de dados atravs de uma conexo JDBC.

O cdigo fonte exibido na Listagem 12 mostra a criao e persistncia


de um objeto do tipo Aluno. Inicialmente alguns imports de objetos so
feitos para se utilizar persistncia com o Hibernate. Em seguida,
dentro do mtodo main, criase um objeto que conter as configuraes
definidas do arquivo hibernate.cfg.xml. A partir deste arquivo, uma
sesso para a persistncia de objetos aberta, juntamente com uma
transao. Ento, criou-se um objeto do tipo Aluno, atribuiu-se valores

21
Curso
Hibernate

para seus atributos e, por fim, invocou-se o mtodo save do objeto


Session. Com isso, uma linha na tabela aluno adicionada de acordo
com os valores definidos no objeto. Assim, a persistncia desejada
realizada e deve-se liberar tanto a transao quanto a sesso com o
Hibernate.

Listagem 12 - Exemplo de Persistncia da Classe Aluno

O cdigo para a criao de um objeto SessionFactory deve ser


chamado uma nica vez durante a execuo da aplicao. Objetos
deste tipo armazenam os mapeamentos e configuraes do Hibernate e
so muitos pesados e lentos de se criar.

A Listagem 13 apresenta o resultado da execuo do cdigo fonte


presente na Listagem 12. No caso, o Hibernate buscou um valor para a
chave primria da tabela, utilizando a seqncia padro
hibernate_sequence. Em seguida, o comando INSERT foi executado
para inserir uma linha na tabela aluno de acordo com as informaes
atribudas ao objeto montado.

22
Curso
Hibernate

Listagem 13 Resultado da Execuo do Cdigo da Listagem 12

A Tabela 3 apresenta alguns dos mtodos que podem ser invocados a


partir do objeto Session.

Tabela 3 - Mtodos invocados a partir do objeto Session

save(Object) Inclui um objeto em uma tabela do banco de


dados.

saveOrUpdate(Object) Inclui um objeto na tabela caso ele ainda no


exista (seja transiente) ou atualiza o objeto
caso ele j exista (seja persistente).

delete(Object) Apaga um objeto da tabela no banco de dados.

get(Class, Serializable Retorna um objeto a partir de sua chave


id) primria. A classe do objeto passada como
primeiro argumento e o seu identificador como
segundo argumento.

Em relao ao mtodo saveOrUpdate, uma questo que se pode


formular a seguinte: Como o Hibernate sabe se o objeto em questo
j existe ou no no banco de dados, ou seja, se ele deve ser criado ou
atualizado? . A resposta simples: se o valor atribudo ao identificador
for diferente de zero, o objeto deve ter sua linha na tabela atualizada
(deve-se garantir que o valor do identificador do objeto se refere a um
valor da chave primria da tabela). Caso contrrio, uma nova linha
ser adicionada tabela.

A Listagem 14 e a Listagem 15 apresentam exemplos dos mtodos


invocados a partir do objeto Session.

23
Curso
Hibernate

Listagem 14 - Exemplo de Busca e Atualizao de um Objeto Aluno

Listagem 15 - Exemplo de Remoo de Objeto Aluno

Os resultados das execues dos cdigos presentes na Listagem 14 e


na Listagem 15 podem ser vistos na Listagem 16 e na Listagem 17,
respectivamente.

Listagem 16 Resultado da Execuo do Cdigo da Listagem 14

Listagem 17 Resultado da Execuo do Cdigo da Listagem 15

10. M APEANDO ATRIBUTOS DA CLASSE

Esta seo destina-se a apresentar alguns exemplos de mapeamentos

24
Curso
Hibernate

de atributos de uma classe. Considerando a classe Cliente exibida na


Figura 7, composta de um conjunto de atributos, onde um deles (id)
corresponde chave primria da tabela correspondente. Dessa forma,
pode-se criar uma tabela cliente na base de dados a partir do script
mostrado na e Listagem 18.

Figura 7 - Classe Cliente

Listagem 18 Script para a Criao da Tabela cliente

A classe Cliente, ilustrada pela Listagem 19, possui exemplos de


mapeamentos de atributos a partir das anotaes: @Column,
@Transient, @Temporal. As anotaes @Id e @GeneratedValue
tambm so utilizadas e servem para mapear a chave primria da
tabela correspondente e definir como o seu valor ser gerado,
respectivamente, como explicado anteriormente.

25
Curso
Hibernate

Listagem 19 Mapeamento da Classe Cliente com Anotaes

A seguir uma breve descrio da utilizao destas anotaes:

Anotao @Transient: informa que o atributo mapeado


no possui correspondente na tabela mapeada pela classe,
ou seja, no um atributo persistente;

Atributos da anotao @Column utilizados:

o name: nome da coluna na tabela do banco de dados


que representa o atributo;

o unique: indica se a coluna na tabela que representa


o atributo possui a restrio de unicidade ou no. Por
padro, assume o valor false;

26
Curso
Hibernate

o nullable: indica se a coluna na tabela que representa


o atributo pode assumir valor nulo ou no. Por
padro, assume o valor true, indicando que pode
assumir valores nulos;

o length: informa o tamanho mximo assumido pelo


valor da coluna na tabela;

o precision: informa a preciso decimal dos possveis


valores para a coluna mapeada pelo atributo;

o insertable: indica se o atributo ser inserido no


momento da insero de uma linha na tabela. Por
padro assume o valor true;

o updatable: indica se o atributo ser atualizado no


momento da atualizao de uma linha na tabela. Por
padro assume o valor true.

Anotao @Temporal: utilizada para mapeamento de datas


e hora. Recebe um valor como argumento que pode ser:

o TemporalType.DATE: usado para mapear datas;

o TemporalType.TIME: usado para mapear hora;

o TemporalType.TIMESTAMP: usado para mapear


datas e hora.

11. ASSOCIAES

O termo associao utilizado para se referir aos relacionamentos


entre as entidades. Os relacionamentos n-para-n, n-para-1 e 1-para-n
so os mais comuns entre as entidades de um banco de dados.

Nas sees seguintes, sero apresentados exemplos de mapeamentos


com anotaes para cada um dos tipos de relacionamentos citados.

11.1 ASSOCIAES 1 - N ( ONE- TO- MANY)

Para exemplificar o relacionamento 1-n, considere o


relacionamento entre a entidade Centro e a entidade
Universidade da Figura 8. O relacionamento diz que uma
universidade possui um conjunto de n centros e um centro est
associado a apenas uma nica universidade. Considere as
classes de domnio Java de uma universidade e de um centro,
respectivamente, mostradas na Listagem 20 e na Listagem 21.

27
Curso
Hibernate

Ambas as classes j possuem o seu mapeamento via anotaes


inserido.

Figura 8 - Relacionamento entre Centro e Universidade

Listagem 20 - Classe de Domnio: Universidade

28
Curso
Hibernate

Listagem 21 - Classe de Domnio: Centro

As classes de domnio Universidade e Centro so mapeadas


para as tabelas universidade e centro, que podem ser criadas
na base de dados a partir dos scripts apresentados na Listagem
22 e na Listagem 23, respectivamente.

Listagem 22 Script para a Criao da Tabela universidade

Listagem 23 Script para a Criao da Tabela centro

A classe de domnio Universidade a que possui um


mapeamento do tipo 1-n atravs do atributo coleo de
centros. O seu mapeamento foi feito na Listagem 20 a partir da

29
Curso
Hibernate

anotao @OneToMany. Como a coleo conter objetos do


tipo Centro, ento est classe tambm dever ser uma classe
persistente da aplicao. Na anotao @OneToMany, existe um
atributo denominado mappedBy que dever receber como valor
o nome do atributo na classe Centro (classe dos tipos de
objetos da coleo) que se refere classe Universidade (onde
h o mapeamento 1-n). Em outras palavras, a tabela centro
possui uma chave estrangeira para a tabela universidade,
representada pelo atributo Universidade universidade da classe
Centro, que corresponder ao atributo mappedBy da anotao
@OneToMany, ou seja, mappedBy= universidade .

J o atributo fecth indica quando o contedo do atributo ser


trazido da base de dados. Pode assumir dois valores:

FetchType.EAGER: sempre que o objeto "pai" for


trazido da base de dados, o atributo mapeado com
fetch=FetchType.EAGER far com que o seu contedo
tambm seja trazido;

FetchType.LAZY: sempre que o objeto "pai" for trazido


da base de dados, o atributo mapeado com
fetch=FetchType.LAZY far com que o seu contedo
somente seja trazido quando acessado pela primeira vez.

A anotao @Cascade, tambm utilizada no mapeamento da


coleo centros, serve para indicar com que ao em cascata o
relacionamento ser tratado, ou seja, especifica quais
operaes devero ser em cascata do objeto pai para o objeto
associado. Por exemplo, pode assumir alguns dos valores
abaixo:

CascadeType.PERSIST: os objetos associados vo ser


inseridos automaticamente quando o objeto "pai" for
inserido;

CascadeType.SAVE_UPDATE: os objetos associados


vo ser inseridos ou atualizados automaticamente
quando o objeto "pai" for inserido ou atualizado;

CascadeType.REMOVE: os objetos associados ao


objeto "pai" vo ser removidos, quando o mesmo for
removido;

CascadeType.REPLICATE: Se o objeto for replicado


para outra base de dados, os filhos tambm sero;

30
Curso
Hibernate

CascadeType.LOCK: Se o objeto for reassociado com a


sesso persistente, os filhos tambm sero;

CascadeType.REFRESH: Se o objeto for sincronizado


com a base de dados, os filhos tambm sero;

CascadeType.MERGE: Se um objeto tiver suas


modificaes mescladas em uma sesso, os filhos
tambm tero;

CascadeType.EVICT: Se o objeto for removido do


cache de primeira nvel, os filhos tambm sero;

CascadeType.ALL: juno de todos os tipos de


cascade.

Para ilustrar o efeito da anotao


@Cascade(CascadeType.ALL), considere o exemplo da
Listagem 24, onde, inicialmente, um objeto Universidade
criado. Em seguida, dois objetos da classe Centro tambm so
criados, recebem valores para seu atributo nome e so
associados ao objeto universidade, que posteriormente
persistido.

Listagem 24 Exemplo de Persistncia OneToMany. Efeito da anotao


@Cascade(CascadeType.ALL)

A Listagem 25 apresenta o resultado da persistncia do objeto


universidade presente na Listagem 24. Observa-se, que a
partir do atributo cascade com valor CascadeType.ALL,
inicialmente inserida uma linha na tabela universidade e em
seguida duas linhas na tabela centro. Vale salientar, que na
hora de inserir as linhas na tabela centro, como os objetos que
as representavam foram associados ao objeto universidade,
automaticamente, o Hibernate atribui como valor de suas

31
Curso
Hibernate

chaves estrangeiras, o valor gerado para a chave primria da


linha criada na tabela universidade.

Listagem 25 Resultado da Execuo do Cdigo da Listagem 24

O atributo centros da classe Universidade foi mapeado com a


anotao @OneToMany e com o atributo
fecth=FetchType.EAGER. A Listagem 26 apresenta um exemplo
de consulta a uma linha na tabela universidade com valor de
chave primria igual a 100. Na Listagem 27 e na Listagem 28
esto os resultados da consulta considerando o atributo fecth
da coleo definido como FetchType.EAGER e como
FetchType.LAZY, respectivamente.

Listagem 26 Consulta para Ilustrar o Uso do Atributo fecth

Listagem 27 Resultado da Execuo do Cdigo da Listagem 26 com


fecth=FetchType.EAGER

32
Curso
Hibernate

Listagem 28 Resultado da Execuo do Cdigo da Listagem 26 com


fecth=FetchType.LAZY

A partir destes resultados, possvel observar que realmente


com o valor FetchType.EAGER, o SQL gerado pelo Hibernate na
consulta de uma universidade realiza um left outer join com a
tabela centro j trazendo os dados da coleo, podendo ser
desnecessrio. Por outro lado, utilizando FetchType.LAZY, a
consulta retorna apenas os dados referentes universidade, de
forma que se fossem necessrios os dados da coleo, bastaria
acessar o atributo que a representa no objeto universidade.

A Listagem 29 apresenta um exemplo com a coleo centros


mapeada com FetchType.LAZY. Neste exemplo, a mesma
consulta universidade de chave primria igual a 100 feita e
em seguida um acesso ao atributo centros, atravs da linha do
cdigo fonte univ.getCentros().iterator(). O resultado pode ser
visto na Listagem 30, em que duas SQLs so geradas, uma
gerada no momento da consulta linha na tabela universidade
de identificador igual a 100 e a outra no momento em que se
itera a coleo centros do objeto anteriormente recuperado.

Listagem 29 Consulta para Ilustrar o Uso do Atributo


fecth=FetchType.LAZY

33
Curso
Hibernate

Listagem 30 Resultado da Execuo do Cdigo da Listagem 29

11.2 ASSOCIAES N-1 (MANY-TO-ONE)

O relacionamento n-1 ser apresentado a partir do


relacionamento existente entre as classes Centro e
Universidade, mostrado tambm na Figura 8. Neste caso, o
relacionamento est presente no mapeamento da classe
Centro, como mostrado na Listagem 21, atravs da anotao
@ManyToOne. Para facilitar o entendimento, o trecho de
mapeamento many-to-one do atributo universidade da classe
Centro pode ser visto tambm na Listagem 31.

Listagem 31 - Mapeamento ManyToOne

A anotao @ManyToOne tambm possui o atributo fetch, que


possui o mesmo comportamento apresentado anteriormente. A
anotao @JoinColumn utilizada para informar qual o nome
da coluna que corresponde chave estrangeira do
mapeamento, no caso, name= id_universidade . Nesta
anotao tambm so aceitveis os atributos insertable e
updatable que se assumirem true indica que o atributo deve
ser inserido (insertable) ou atualizado (updatable) no momento
em que o objeto que possui o relacionamento inserido ou
atualizado, respectivamente. O atributo do relacionamento no

34
Curso
Hibernate

ser inserido se insertable = false e no ser atualizado se


updatable = false.

Outra anotao utilizada a @Fecth, que define como o


atributo mapeado ser recuperado da base de dados. Pode
assumir trs valores:

FetchMode.JOIN: utiliza outer join para carregar


entidades ou colees mapeadas;

FetchMode.SELECT: utiliza um novo select para


carregar entidades ou colees mapeadas;

FetchMode.SUBSELECT: utiliza uma consulta subselect


adicional para carregar colees adicionais. No
permitido para mapeamentos ManyToOne.

A Listagem 32 apresenta uma consulta base de dados do


centro com valor de chave primria igual a 110. A Listagem 33
apresenta o resultado da consulta com o mapeamento do
atributo universidade da classe Centro utilizando a anotao
@Fecth recebendo com valor FetchMode.JOIN. Pode-se
observar que uma nica consulta feita, realizando um JOIN
entre as tabelas centro e universidade. J na Listagem 34, o
resultado da consulta com o uso da anotao @Fetch com o
valor FetchMode.SELECT resulta em duas consultas SELECT
base de dados, uma para buscar as informaes do centro de
chave primria igual a 110 e a outra para buscar as
informaes da universidade associada.

Listagem 32 Consulta para Ilustrar o Uso da Anotao @Fecth

35
Curso
Hibernate

Listagem 33 Resultado da Execuo do Cdigo da Listagem 32 com


@Fetch(FetchMode.JOIN)

Listagem 34 Resultado da Execuo do Cdigo da Listagem 32 com


@Fetch(FetchMode.SELECT)

11.3 ASSOCIAES N-N (MANY-TO-MANY)

O relacionamento n-n ser feito a partir do relacionamento


entre as entidades Departamento e Curso mostrado na Figura
9.

Figura 9 - Relacionamento n-n entre Curso e Departamento

Um relacionamento n-n implica em existir uma nova tabela


para mapear o relacionamento no banco de dados. Vamos
denominar essa nova tabela como DEPARTAMENTO_CURSO,
como mostrado na Figura 10. Dessa forma, um departamento
possui uma coleo de cursos e um curso uma coleo de
departamentos. A existncia dessas colees nas classes de
domnio opcional. Por exemplo, pode ser que em um sistema

36
Curso
Hibernate

real no seja necessrio saber todos os departamentos de


determinado curso, mas se for realmente necessrio, o
Hibernate apresenta outros mecanismos para a obteno desta
informao.

Figura 10 - Tabela de relacionamento DEPARTAMENTO_CURSO

Para criar as tabelas curso, departamento e


departamento_curso, pode-se utilizar os scripts presentes na
Listagem 35, na Listagem 36 e na Listagem 37,
respectivamente.

Listagem 35 - Script para a Criao da Tabela curso

Listagem 36 - Script para a Criao da Tabela departamento

Listagem 37 - Script para a Criao da Tabela departamento_curso

37
Curso
Hibernate

As classes Java das entidades Departamento e Curso esto


ilustradas na Listagem 38 e Listagem 39, respectivamente.
Ambas as classes possuem mapeamentos de colees com o
relacionamento n-n, que feito a partir da anotao
@ManyToMany. Para este mapeamento, foi preciso tambm do
uso da anotao @JoinTable para informar qual a tabela
intermediria entre as entidades Departamento e Curso.

A anotao @JoinTable possui o atributo name que onde


informado o nome da tabela intermediria que representa o
mapeamento n-n, no caso, a tabela departamento_curso.
Possui tambm o atributo schema, onde dever ser informado o
esquema da base de dados em que a tabela se encontra. J o
atributo joinColumns recebe como valor uma anotao
@JoinColumn, informando qual o nome da coluna na tabela
intermediria que representa a classe onde se est fazendo o
mapeamento n-n. Em relao ao mapeamento na tabela
Departamento, a coluna na tabela intermediria
departamento_curso que a representa se chama
id_departamento. Por fim, no atributo inverseJoinColumns deve
ser informada qual a coluna que representa a outra entidade
no relacionamento n-n. No mapeamento da classe
Departamento, a outra classe do relacionamento a classe
Curso, portanto, a coluna na tabela intermediria que a
representa id_curso.

38
Curso
Hibernate

Listagem 38 - Classe de Domnio: Departamento

Na classe Curso tambm h o mapeamento de um


relacionamento n-n com a coleo departamentos. A explicao
semelhante ao mapeamento da coleo cursos na classe
Departamento.

39
Curso
Hibernate

Listagem 39 - Classe de Domnio: Curso

O cdigo presente na Listagem 40 cria um instncia de um


objeto Departamento. Em seguida recupera um objeto
persistente da classe Centro com identificador igual a 110 e
outro da classe Curso com identificador igual a 220. O objeto
Curso adicionado na coleo de cursos do objeto
Departamento criado. Por fim, o departamento persistido.

40
Curso
Hibernate

Listagem 40 Exemplo com Mapeamento Usado a Anotao @ManyToMany:


Persistncia de Departamento

O SQL gerado apresentado na Listagem 41. Observa-se que


SELECTs na tabela centro, na tabela curso e na seqncia
hibernate_seq so realizados.

Depois, feito e um INSERT na tabela departamento e em


seguida, uma incluso de linha na tabela de relacionamento
departamento_curso, devido ao mapeamento n-n na classe
Departamento.

Listagem 41 Resultado da Execuo do Cdigo Presente na Listagem 40

41
Curso
Hibernate

11.4 ASSOCIAES N-N COM ATRIBUTOS

Imagine que seria necessrio guardar a data em que foi feita a


associao entre um determinado curso e um determinado
departamento, ou seja, necessrio ter um novo atributo na
tabela departamento_curso. Dessa forma, esta tabela no seria
formada apenas pelos identificadores das tabelas curso e
departamento, mas sim tambm pela data. Para essa situao,
os mapeamentos dos relacionamentos com a anotao
@ManyToMany nas classes Departamento e Curso no
resolveriam o problema. Ento, deve-se criar uma nova classe
DepartamentoCurso, como mostrado no diagrama da Figura
11, formada por uma chave primria composta por dois
elementos e por um atributo que representa a data.

Figura 11 - Mapeamento n-n com Atributo

Para adicionar a coluna data tabela departamento_curso,


basta utilizar o script apresentado na Listagem 42.

Listagem 42 - Script para a Adio da Coluna data na Tabela


departamento_curso

Com a adio da coluna data, deve ser feito o mapeamento da


tabela departamento_curso como mostrado na Listagem 43 a
partir da classe DepartamentoCurso. Pode-se observar que a
chave composta representada pelo atributo chaveComposta
do tipo DepartamentoCursoPK e mapeada pela anotao
@EmbeddedId.

A classe DepartamentoCursoPK representa a chave primria


composta e mapeada como mostrado na seo seguinte.

42
Curso
Hibernate

Listagem 43 - Classe de Domnio: DepartamentoCurso

11.4.1 Composite-id

Para mapear uma chave composta, deve-se criar uma


classe que a represente. Esta classe deve ser mapeada
com a anotao @Embeddable, como mostrado na
Listagem 44 no mapeamento da chave composta
DepartamentoCursoPK. Dentro desta classe deve-se
mapear os atributos que compem a chave composta
das maneiras vistas anteriormente. importante
ressaltar que a classe que representa a chave composta
deve implementar a interface Serializable.

Listagem 44 - Classe de Domnio: DepartamentoCursoPK

Para exemplificar o relacionamento n-n com atributos,


observe o exemplo da Listagem 45. Primeiro um
departamento e um curso so buscados na base de
dados, ambos com identificadores iguais a 1. Em

43
Curso
Hibernate

seguida, cria-se uma instncia de um objeto da classe


DepartamentoCursoPK que representa a chave
composta. Os valores que compem a chave, curso e
departamento, so atribudos. Finalmente, cria-se um
objeto da classe DepartamentoCurso que representa a
tabela de relacionamento entre as entidades, define-se a
sua chave composta e a data de criao, persistindo-o
na base de dados.

Listagem 45 Exemplo com Mapeamento de Chave Composta

O resultado da execuo do cdigo presente na Listagem


45 pode ser visto na Listagem 46.

44
Curso
Hibernate

Listagem 46 Resultado da Execuo do Cdigo Presente na


Listagem 45

11.5 ASSOCIAES 1-1 (ONE-TO-ONE)

Considere o relacionamento 1-1 entre as entidades


Universidade e Endereo mostrado na Figura 12. Uma
universidade tem um nico endereo e um endereo pertence
apenas a uma nica universidade.

Figura 12 - Exemplo de Relacionamento 1-1

A Listagem 20 e a Listagem 47 apresentam as classes Java


para as entidades Universidade e Endereco, respectivamente.

45
Curso
Hibernate

Na classe Endereco, o relacionamento 1-1 com a classe


Universidade mapeado atravs da anotao @OneToOne e da
anotao @JoinColumn usada para informar o nome da coluna
que representa a chave estrangeira para a tabela universidade.

Listagem 47 - Classe de Domnio: Endereo

A tabela endereo pode ser criada a partir do script exibido na


Listagem 48.

Listagem 48 - Script para a Criao da Tabela endereco

Para finalizar o mapeamento 1-1 entre as classes Universidade


e Endereo, deve ser includo na classe Universidade o atributo
endereco tambm mapeado com a anotao @OneToOne,
como mostrado na Listagem 49. No mapeamento 1-1 na classe
Universidade, como em sua tabela no h chave estrangeira

46
Curso
Hibernate

para a tabela endereco, deve-se informar qual atributo na


classe Universidade refere-se ao mapeamento 1-1 do outro
lado, no caso o atributo universidade, informado pelo atributo
mappedBy da anotao @OneToOne.

Tambm utilizada a anotao @Cascade passando como


argumento CascadeType.ALL, informando que no momento que
se inserir, atualizar ou remover uma universidade, a operao
deve ser cascateada para a coluna da tabela.

Listagem 49 Incluso de Atributo endereco na classe Universidade

Para ilustrar o uso deste mapeamento, considere o exemplo


mostrado na Listagem 50, onde, incialmente, objetos da classe
Endereco e Universidade so criados. Em seguida, associa-se a
universidade ao endereo e o endereo a universidade. Por fim,
o objeto universidade persistido na base de dados.

A Listagem 51 apresenta o resultado da execuo do cdigo


presente na Listagem 50. Observa-se a universidade
persistida na base de dados e em seguida, o endereo tambm
fazendo a associao com a universidade criada.

Listagem 50 Exemplo para Ilustrar Mapeamento 1-1

47
Curso
Hibernate

Listagem 51 Resultado da Execuo do Cdigo Presente na Listagem 50

12. DEFINIO DE CHAVE PRIMRIA

Nos mapeamentos apresentados at o momento, a definio dos


valores das chaves primrias foi feita apenas utilizando a seqncia
hibernate_sequence. O exemplo presente na Listagem 52 mostra o
mapeamento da chave primria da tabela cliente utilizando a seqncia
de nome cliente_seq. Para isso, utilizou-se as anotaes
@SequenceGenerator e @GeneratedValue.

Na anotao @SequenceGenerator define-se qual seqncia criada na


base de dados ser utilizada para o mapeamento. No caso, nomeia-se
a seqncia com o nome SEQ_CLIENTE (name = SEQ_CLIENTE ).

Para definir qual seqncia ser utilizada no mapeamento da chave


primria, utiliza-se a anotao @GeneratedValue, onde informado
que a definio do valor do atributo ser atravs de seqncias
(strategy = GenerationType.SEQUENCE) e o nome da mesma
(generator = "SEQ_CLIENTE").

Listagem 52 Mapeamento de Chave Primria Usando Seqncia Prpria

48
Curso
Hibernate

13. COLEES

O mapeamento de colees j foi apresentado no contexto dos


relacionamentos atravs da anotao @OneToMany. Essa seo est
destinada a apresentar o mapeamento dos quatro tipos de colees
existentes (Set, Bag, List e Map), porm formadas por tipos primitivos.

13.1 Set

Para exemplificar o mapeamento de um Set de tipos primitivos


considere o mapeamento de uma coleo de String s para
armazenar os telefones de um Aluno, como visto na Figura 13.
Ento, na classe Aluno deve-se inserir o atributo telefones com
seu mapeamento anotado, como mostrado na Listagem 53.

Figura 13 - Coleo de telefones para Aluno: Set

Para mapear esta coleo foi utilizada a anotao


@CollectionOfElements. A anotao @JoinTable utlizada para
informar o nome da tabela e esquema onde a coleo dos
elementos mapeados sero armazendos, no caso atravs dos
atributos name= aluno_telefone e schema= anotacoes . Na
anotao @JoinTable tambm informada o nome da coluna
que representa a classe onde a coleo est sendo mapeada,
no caso a classe Aluno. Para informar esta coluna, utiliza-se o
atributo joinColumns que recebe como valor a anotao
@JoinColumn com o nome da coluna, no caso id_aluno. Por
fim, informa-se a coluna que representar a informao do
telefone utilizando a anotao @Column.

Os telefones do aluno so armazenados na tabela


aluno_telefone. Para o banco de dados est tabela separada
da tabela aluno, mas para o Hibernate, ele cria a iluso de uma
nica entidade.

49
Curso
Hibernate

Listagem 53 Atributo telefones Inserido na Classe Aluno (Set)

Um Set no pode apresentar elementos duplicados, portanto a


chave primria de aluno_telefone consiste nas colunas id_aluno
e telefone. O script para a criao da tabela aluno_telefone
est presente na Listagem 54.

Listagem 54 - Script para a Criao da Tabela aluno_endereo

Dado o mapeamento da coleo de telefones de Aluno, observe


o exemplo mostrado na Listagem 55. Neste exemplo, cria-se
um objeto Aluno que ter valores para seus atributos definidos,
inclusive dois nmeros de telefone inseridos em sua coleo de
String s. Por fim, o objeto Aluno persistido. O resultado
mostrado na Listagem 56, onde primeiro inserida uma linha
na tabela aluno e posteriormente duas linhas na tabela
aluno_telefone.

50
Curso
Hibernate

Listagem 55 - Exemplo de Mapeamento de Set

Listagem 56 - Resultado da Execuo do Cdigo Presente na Listagem 55

13.2 List

Um List uma coleo ordenada que pode conter elementos


duplicados. O mapeamento de uma lista requer a incluso de
uma coluna de ndice na tabela do banco de dados. A coluna
ndice define a posio do elemento na coleo, como visto na
Figura 14, a coluna ndice representada pela coluna posio
da tabela aluno_telefone. Dessa maneira, o Hibernate pode
preservar a ordenao da coleo quando recuperada do banco
de dados e for mapeada como um List.

Figura 14 - Coleo de telefones para Aluno: List

51
Curso
Hibernate

Para mapear a coleo de telefones da classe Aluno, define o


atributo telefones como mostrado na Listagem 57. A diferea
a incluso da definio do ndice atravs da anotao
@IndexColumn(name = posio ), informando a coluna que
ele representa na tabela.

Listagem 57 Atributo telefones Inserido na Classe Aluno (List)

Mapeando a coleo como um List, a chave primria da tabela


ALUNO_TELEFONE passa a ser as colunas ID_ALUNO e
POSICAO, permitindo a presena de telefones (TELEFONE)
duplicados na coleo.

Para exemplificar, considera-se o exemplo presente na


Listagem 58, com resultado de execuo presente na Listagem
59.

Listagem 58 - Exemplo de Mapeamento de List

Listagem 59 - Resultado da Execuo do Cdigo Presente na Listagem 58

52
Curso
Hibernate

13.3 Map

Maps associam chaves aos valores e no podem conter chaves


duplicadas. Eles diferem de Sets no fato de que contm chaves
e valores, ao passo que os Sets contm somente a chave.

O mapeamento de um Map semelhante ao de um List, onde o


ndice de posio passa a ser a chave. Veja a Figura 14. A
Listagem 60 apresenta a coleo de telefones sendo mapeada
como um Map. A chave primria da tabela aluno_telefone
passa a ser as colunas id_aluno e chave, tambm permitindo a
presena de telefones duplicados na coleo. A diferena dos
outros mapeamentos que a chave mapeada atravs da
anotao @MapKey(columns = {@Column(name = "chave")}).

Figura 15 - Coleo de telefones para Aluno: Map

Listagem 60 Atributo telefones Inserido na Classe Aluno (Map)

Para exemplificar, considera-se o exemplo presente na


Listagem 61, com resultado de execuo presente na Listagem
62.

53
Curso
Hibernate

Listagem 61 - Exemplo de Mapeamento de Map

Listagem 62 - Resultado da Execuo do Cdigo Presente na Listagem 61

13.4 Bag

Um Bag consiste em uma coleo desordenada que permite


elementos duplicados. Em Java no h implementao de um
Bag, contudo o Hibernate fornece um mecanismo de que um
List em Java simule o comportamento de um Bag. Pela
definio de um List, uma lista uma coleo ordenada,
contudo o Hibernate no preserva a ordenao quando um List
persistido com a semntica de um Bag. Para usar o Bag, a
coleo de telefones deve ser definida com o tipo List. Um
exemplo de mapeamento de um Bag pode ser visto na Figura
16 e na Listagem 63.

Figura 16 - Coleo de telefones para Aluno: Bag

Para simular o Bag como List, a chave primria no deve ter

54
Curso
Hibernate

associao com a posio do elemento na tabela, assim ao


invs da anotao @IndexColumn, utiliza-se a anotao
@CollectionId, onde uma chave substituta diferente atribuda
a cada linha da tabela na coleo. Entretanto, o Hibernate no
fornece nenhum mecanismo para descobrir o valor chave
substituta de uma linha em particular.

Para o exemplo, a chave substituta representada pela coluna


id_aluno_telefone da table aluno_telefone. necessrio
informar como os seus valores sero gerados, neste caso,
utlizada uma seqncia. A anotao @SequenceGenerator
serve para definir o nome de uma seqncia no banco de
dados. O atributo name informa como ser denominada a
seqncia, j o atributo sequenceName informa qual seqncia
se est utilizando.

A anotao @CollectionId utlizada para definir a chave


substituta. No atributo columns informa-se qual o nome da
coluna na tabela; o atributo generator informa qual seqncia
est sendo utilizada para gerar seus valores (no caso
SEQ_HIBERNATE definida na anotao @SequenceGenerator);
e o atributo type utilizado para informar o tipo desta coluna,
no caso integer.

Listagem 63 Atributo telefones Inserido na Classe Aluno (Bag)

Para exemplificar, considera-se o exemplo presente na


Listagem 58, onde a coleo agora est mapeada com
semntica de Bag, com resultado de execuo presente na
Listagem 64. Observa-se que a seqncia hibernate_sequence
invocada duas vezes: uma para o valor da chave primria do
objeto Aluno e outra para o valor da chave substitua da coleo
de telefones.

55
Curso
Hibernate

Listagem 64 - Resultado da Execuo do Cdigo Presente na Listagem 58

14. TRANSAES

Uma transao uma unidade de execuo indivisvel (ou atmica).


Isso significa dizer que todas as etapas pertencentes a uma transao
so completamente finalizadas ou nenhuma delas termina.

Para exemplificar o conceito de transaes, considere um exemplo


clssico de transferncia entre contas bancrias: transferir R$ 150,00
da conta corrente do cliente A para a conta corrente do cliente B.
Basicamente, as operaes que compem a transao so:

1) Debitar R$ 150,00 da conta corrente do cliente A

2) Creditar R$ 150,00 na conta corrente do cliente B

Para a efetivao da transao descrita acima, seria necessrio seguir


os seguintes passos:

1) Ler o saldo da conta corrente A (xA)

2) Calcular o dbito de R$ 150,00 da conta corrente A (dA =


xA 150,00)

3) Gravar na base de dados o novo saldo da conta corrente A


(xA = dA)

4) Ler o saldo da conta corrente B (xB)

5) Calcular o crdito de R$ 150,00 na conta corrente B (dB =


xB + 150,00)

6) Gravar na base de dados o novo saldo da conta corrente B


(xB = dB)

Caso ocorra algum problema (por exemplo: falta de energia, falha no


computador, falha no programa, etc.), a execuo dos passos
anteriores pode ser interrompida. Se, por exemplo, houvesse

56
Curso
Hibernate

interrupo logo aps a execuo do 3 passo, a conta A teria um


dbito de R$ 150,00 e ainda no teria sido creditado R$ 150,00 na
conta corrente B. Neste caso, o banco de dados estaria em um estado
inconsistente, afinal, R$ 150,00 teriam sumido da conta A sem
destino. Dessa maneira, de suma importncia garantir que esses
seis passos sejam totalmente executados. Caso haja alguma falha
antes da concluso do ltimo passo, deve-se garantir tambm que os
passos j executados sero desfeitos, de forma que ou todos os
passos so executados ou todos os passos no so executados. Para
garantir a consistncia do banco, esses seis passos devem ser
executados dentro de uma transao, j que ela uma unidade de
execuo atmica.

Resumindo, uma transao garante que a seqncia de operaes


dentro da mesma seja executada de forma nica, ou seja, na
ocorrncia de erro em alguma das operaes dentro da transao
todas as operaes realizadas desde o incio podem ser revertidas e
as alteraes no banco de dados desfeitas, garantindo assim, a
unicidade do processo. A transao pode ter dois fins: commit ou
rollback.

Quando a transao sofre commit, todas as modificaes nos dados


realizadas pelas operaes presentes na transao so salvas.
Quando a transao sofre rollback, todas as modificaes nos dados
realizadas pelas operaes presentes na transao so desfeitas.

Para que um banco de dados garanta a integridade dos seus dados


deve possuir quatro caractersticas, conhecidas como ACID:

Atomicidade: o banco de dados deve garantir que todas as


transaes sejam indivisveis.

Consistncia: aps a execuo de uma transao, o banco de


dados deve continuar consistente, ou seja, deve continuar com
um estado vlido.

Isolamento: mesmo que vrias transaes ocorram


paralelamente (ou concorrentemente), nenhuma transao
deve influenciar nas outras. Resultados parciais de uma
transao no devem ser vistos por outras transaes
executadas concorrentemente.

Durabilidade: aps a finalizao de uma transao, todas as


alteraes feitas por ela no banco de dados devem ser

57
Curso
Hibernate

durveis, mesmo havendo falhas no sistema aps a sua


finalizao.

14.1 MODELOS DE TRANSAES

As definies do incio de uma transao, de seu fim e das


aes que devem ser tomadas na ocorrncia de falhas so
feitas atravs de um modelo de transao.

Existem diversos modelos encontrados na literatura. Nesta


seo sero abordados apenas quatro: Flat Transactions,
Nested Transactions, Chained Transactions e Join Transactions.

Flat Transaction. Modelo mais utilizado pela maioria dos


Sistemas Gerenciadores de Banco de Dados (SGBD) e
Gerenciadores de Transaes. Conhecida como modelo
de transaes planas por apresentar uma nica camada
de controle, ou seja, todas as operaes dentro da
transao so tratadas como uma nica unidade de
trabalho.

Nested Transaction. Este modelo, tambm conhecido


como Modelo de Transaes Aninhadas, possibilita que
uma transao possa ser formada por vrias sub-
transaes. Em outras palavras, uma nica transao
pode ser dividida em diversas unidades de trabalho, com
cada unidade operando independente uma das outras. A
propriedade de atomicidade vlida para as sub-
transaes. Alm disso, uma transao no pode ser
validada at que todas as suas sub-transaes tenham
sido finalizadas. Se uma transao for interrompida,
todas as suas sub-transaes tambm sero. O contrrio
no verdadeiro, j que se uma sub-transao for
abortada a transao que a engloba pode: ignorar o
erro; desfazer a sub-transao; iniciar uma outra sub-
transao.

Chained Transaction. Tambm conhecido como Modelo


de Transaes Encadeadas, esse modelo tem como
objetivo desfazer as operaes de uma transao em
caso de erro com a menor perda de trabalho possvel.
Uma transao encadeada consiste em um conjunto de
sub-transaes executadas seqencialmente, em que
medida que as sub-transaes vo sendo executadas,
so validadas e no podem mais ser desfeitas. Os

58
Curso
Hibernate

resultados do conjunto de transaes s sero visveis


ao final da execuo de todas elas.

Join Transaction. Esse modelo permite que duas


transaes sejam unidas em uma s, de forma que
todos os recursos passam a ser compartilhados.

14.2 TRANSAES E BANCO DE DADOS

Uma transao de banco de dados formada por um conjunto


de operaes que manipulam os dados. A atomicidade de uma
transao garantida por duas operaes: commit e rollback.

Os limites das operaes de uma transao devem ser


demarcados. Assim, possvel saber a partir de qual operao
a transao iniciada e em qual operao ela finalizada. Ao
final da execuo da ltima operao que pertence
transao, todas as alteraes no banco de dados realizadas
pelas operaes que compe a transao devem ser
confirmadas, ou seja, um commit realizado. Se houver algum
erro durante a execuo de algumas das suas operaes, todas
as operaes da transao que j foram executadas devem ser
desfeitas, ou seja, um rollback realizado. A Figura 21 ilustra
esses conceitos.

Figura 21 - Estados do sistema durante uma transao

14.3 AMBIENTES GERENCIADOS E NO GERENCIADOS

As sees seguintes referem-se s definies dos conceitos


relacionados a transaes JDBC e JTA, onde aparecem os

59
Curso
Hibernate

termos ambientes gerenciados e no gerenciados. Esta seo


destina-se a explicar sucintamente o que so esses termos.

Os ambientes gerenciados so aqueles caracterizados pela


gerncia automtica de transaes realizadas por algum
container. Exemplos de ambientes gerenciados so
componentes EJB (Enteprise JavaBeans) executando em
servidores de aplicaes (JBoss, Geronimo, etc). J os
ambientes no gerenciados so cenrios onde no h nenhuma
gerncia de transao, como por exemplo: Servlets, aplicaes
desktop, etc.

14.4 TRANSAES JDBC

A tecnologia JDBC (Java Database Connectivity) um conjunto


de classes e interfaces escritas em Java, ou API, que realiza o
envio de instrues SQL (Structured Query Language) para
qualquer banco de dados relacional.

Uma transao JDBC controlada pelo gerenciador de


transaes SGBD e geralmente utilizada por ambientes no
gerenciados. Utilizando um driver JDBC, o incio de uma
transao feito implicitamente pelo mesmo. Embora alguns
bancos de dados necessitem invocar uma sentena begin
transaction explicitamente, com a API JDBC no preciso
fazer isso. Uma transao finalizada aps a chamada do
mtodo commit(). Caso algo acontea de errado, para desfazer
o que foi feito dentro de uma transao, basta chamar o
mtodo rollback(). Ambos, commit() e rollback(), so
invocados a partir da conexo JDBC.

A conexo JDBC possui um atributo auto-commit que especifica


quando a transao ser finalizada. Se este atributo for
definido como true, ou seja, se na conexo JDBC for invocado
setAutoCommit(true), ativa-se o modo de auto commit. O
modo auto commit significa que para cada instruo SQL uma
nova transao criada e o commit realizado imediatamente
aps a execuo e finalizao da mesma, no havendo a
necessidade de aps cada transao invocar explicitamente o
mtodo commit().

Em alguns casos, uma transao pode envolver o


armazenamento de dados em vrios bancos de dados. Nessas
situaes, o uso apenas do JDBC pode no garantir a

60
Curso
Hibernate

atomicidade. Dessa maneira, necessrio um gerenciador de


transaes com suporte a transaes distribudas. A
comunicao com esse gerenciador de transaes feita
usando JTA (Java Transaction API).

14.5 TRANSAES JTA

As transaes JTA so usadas em um ambiente gerencivel,


onde existem transaes CMT (Container Managed
Transactions). Neste tipo de transao no h a necessidade
de programao explcita das delimitaes das transaes, esta
tarefa realizada automaticamente pelo prprio container.
Para isso, necessrio informar nos descritores dos EJBs a
necessidade de suporte transacional s operaes e como ele
deve gerenci-lo.

O gerenciamento de transaes feito pelo Hibernate a partir


da interface Transaction.

14.6 API PARA TRANSAES DO HIBERNATE

A interface Transaction fornece mtodos para a declarao dos


limites de uma transao. A Listagem 80 apresenta um
exemplo de uso de transaes com a interface Transaction.

A transao iniciada a partir da invocao ao mtodo


session.beginTransaction(). No caso de um ambiente no
gerenciado, uma transao JDBC na conexo JDBC iniciada.
J no caso de um ambiente gerenciado, uma nova transao
JTA criada, caso no exista nenhuma j criada. Casa j existe
uma transao JTA, essa nova transao une-se a existente.

A chamada ao mtodo tx.commit() faz com que os dados em


memria sejam sincronizados com a base de dados. O
Hibernate s realiza efetivamente o commit se o comando
beginTransaction() iniciar uma nova transao (em ambos
ambientes gerenciado ou no gerenciado). Se o
beginTransaction() no iniciar uma nova transao (no caso de
transaes JTA isso possvel), ento o estado em sesso
apenas sincronizado com o banco de dados e a finalizao da
transao feita de acordo com a primeira parte do cdigo
fonte que a criou.

Se ocorrer algum erro durante a execuo do mtodo


acaoExecutada(), o mtodo tx.rollback() executado,

61
Curso
Hibernate

desfazendo o que foi feito at o momento em que o erro


ocorreu.

Observa-se que no final do cdigo a sesso finalizada a partir


do comando session.close(), liberando a conexo JDBC e
devolvendo-a para o pool de conexes.

Listagem 80 - Usando a Interface Transaction do Hibernate

14.7 FLUSHING

Flushing o processo de sincronizar os dados em sesso (ou


em memria) com o banco de dados. As mudanas nos objetos
de domnio em memria feitas dentro do escopo de uma
sesso (Session) no so imediatamente propagadas para o
banco de dados. Isso permite ao Hibernate unir um conjunto
de alteraes e fazer um nmero mnimo de interaes com o
banco de dados, ajudando a minimizar a latncia na rede.

A operao de flushing ocorre apenas em trs situaes:


quando dado commit na transao, algumas vezes antes de
uma consulta ser executada (em situaes que alteraes
podem influenciar em seu resultado) e quando o mtodo
Session.flush() invocado.

O Hibernate possui um modo flush que pode ser definido a


partir do comando session.setFlushMode(). Este modo pode
assumir os seguintes valores:

FlushMode.AUTO: valor padro. Faz com que o Hibernate


no realize o processo de flushing antes de todas as
consultas, somente realizar se as mudanas dentro da
transao alterar seu resultado.

FlushMode.COMMIT: especifica que os estados dos


objetos em memria somente sero sincronizados com a

62
Curso
Hibernate

base de dados ao final da transao, ou seja, quando o


mtodo commit() chamado.

FlushMode.NEVER: especifica que a sincronizao s


ser realizado diante da chamada explcita ao mtodo
flush().

14.8 NVEIS DE ISOLAMENTO DE UMA TRANSAO

As bases de dados tentam assegurar que uma transao


ocorra de forma isolada, ou seja, mesmo que estejam
acontecendo outras transaes simultaneamente, como se
ela estivesse ocorrendo sozinha.

O nvel de isolamento de uma transao especifica quais dados


esto visveis a uma sentena dentro de uma transao. Eles
impactam diretamente no nvel de acesso concorrente a um
mesmo alvo no banco de dados por transaes diferentes.

Geralmente, o isolamento de transaes feito usando locking,


que significa que uma transao pode bloquear
temporariamente um dado para que outras transaes no o
acessem no momento que ela o est utilizando. Muitos bancos
de dados implementam o nvel de isolamento de uma
transao atravs do modelo de controle concorrente multi-
verses (MCC Multiversion Concorrency Control).

Dentre alguns fenmenos que podem ocorrer devido quebra


de isolamento de uma transao esto trs:

Dirty Read (Leitura Suja): uma transao tem acesso a


dados modificados por uma outra transao ainda no
finalizada que ocorre concorrentemente. Isso pode
causar problema, pois pode ocorrer um erro dentro da
transao que est modificando os dados e as suas
alteraes serem desfeitas antes de confirmadas, ento
possvel que a transao que acessa os dados j
modificados esteja trabalhando se baseando em dados
incorretos.

Nonrepeatable Read (Leitura que no pode ser


repetida): uma transao l mais de uma vez um
mesmo dado e constata que h valores distintos em
cada leitura. Por exemplo, uma transao A l uma linha
do banco; uma transao B modifica essa mesma linha e

63
Curso
Hibernate

finalizada (commit) antes que a transao A; a


transao A l novamente esta linha e obtm dados
diferentes.

Phantom Read (Leitura Fantasma): em uma mesma


transao uma consulta pode ser executada mais de
uma vez e retornar resultados diferentes. Isso pode
ocorrer devido a uma outra transao realizar mudanas
que afetem os dados consultados. Por exemplo, uma
transao A l todas as linhas que satisfazem uma
condio WHERE; uma transao B insere uma nova
linha que satisfaz a mesma condio antes da transao
A ter sido finalizada; a transao A reavalia a condio
WHERE e encontra uma linha fantasma na mesma
consulta feita anteriormente.

Existem quatro nveis de isolamento da transao em SQL. Eles


se diferenciam de acordo com a ocorrncia ou no dos
fenmenos anteriormente descritos, como mostrado na Tabela
4.

Nvel de Dirty Read Nonrepeatable Phanton Read


Isolamento

Read Uncommited SIM SIM SIM

Read Commited NO SIM SIM

Repeatable Read NO NO SIM

Serializable NO NO NO

Tabela 4 - Nveis de Isolamento da Transao em SQL

A escolha do nvel de isolamento Read Uncommited no


recomendada para banco de dados relacionais, j que permite
ler inconsistncias e informaes parciais (mudanas realizadas
por uma transao ainda no finalizada podem ser lidas por
outra transao). Se a primeira transao no for concluda,
mudanas na base de dados realizadas pela segunda transao
podem deix-la com um estado inconsistente.

Com o nvel Read Commited, uma transao somente visualiza


mudanas feitas por outras transaes quando confirmadas,
permitindo que transaes s acessem estados consistentes do
banco. No caso de uma atualizao/excluso de uma linha de
alguma tabela por uma transao, pode ser que a mesma

64
Curso
Hibernate

tenha acabado de ser modificada por uma transao


concorrente. Nesta situao, a transao que pretende
atualizar fica esperando a transao de atualizao que iniciou
primeiro ser efetivada ou desfeita. Se as atualizaes da
primeira transao forem desfeitas, seus efeitos sero
desconsiderados e a segunda transao efetivar suas
mudanas considerando a linha da tabela anteriormente lida.
Caso contrrio, a segunda transao ir ignorar a atualizao
caso a linha tenha sido excluda ou aplicar a sua atualizao
na verso atualizada da linha.

O nvel Repeatable Read no permite que uma transao


sobrescreva os dados alterados por uma transao
concorrente. Uma transao pode obter uma imagem completa
da base de dados quando iniciada. Este nvel ideal para a
gerao de relatrios, pois em uma mesma transao, um
registro lido diversas vezes e seu valor se mantm o mesmo
at que a prpria transao altere seu valor.

Em relao ao nvel Serializable, ele fornece o nvel de


isolamento de transao mais rigoroso. Ele permite uma
execuo serial das transaes, como se todas as transaes
fossem executadas uma atrs da outra. Dessa forma, pode-se
perder um pouco do desempenho da aplicao.

14.9 CONFIGURANDO O NVEL DE ISOLAMENTO

No Hibernate cada nvel de isolamento identificado por um


nmero:

1: Read Uncommited

2: Read Commited

4: Repeatable Read

8: Serializable

Para configur-lo basta incluir a linha presente na Listagem 81


no arquivo de configurao *.cfg.xml. Neste exemplo, o nvel
de isolamento foi definido como Repeatable Read.

65
Curso
Hibernate

Listagem 81 Configurao do Nvel de Isolamento

15. CONCORRNCIA

Em algumas situaes pode acontecer que duas ou mais transaes


que ocorrem paralelamente leiam e atualizem o mesmo dado.
Considerando que duas transaes leiam um mesmo dado x quase que
simultaneamente. Ambas as transaes vo manipular esse mesmo
dado com operaes diferentes e atualiz-lo na base de dados. Para
exemplificar, a Listagem 82 apresenta um exemplo de duas transaes
concorrentes manipulando o mesmo dado x.

No primeiro passo, ambas as transaes lem o dado x com o mesmo


valor (2). Em seguida, T1 soma o valor x que leu com 1 e o valor de x
para T1 passa a ser 3 (2 + 1). J T2, soma o valor de x lido a 3 e x
passa a ter o valor 5 (2 + 3). Por fim, ambos T1 e T2 gravaro os
novos valores de x calculados na base de dados, respectivamente.
Como no h controle de concorrncia de acesso ao dado x, o seu
valor final corresponder a 5, ou seja, o valor calculado por T2,
significando que as alteraes feitas por T1 foram descartadas.

Listagem 82 Exemplo de Transaes Concorrentes

Para evitar a situao descrita anteriormente, deve-se controlar o


acesso concorrente ao dado, ou seja, deve-se implementar o
mecanismo de Locking. O gerenciamento de locking e da concorrncia
pode ser feito de duas formas:

Pessimista: utilizar o controle pessimista significa que se uma


transao T1 l um dado e tem a inteno de atualiz-lo, esse
dado ser bloqueado (nenhuma outra transao poder l-lo)
at que T1 o libere, normalmente aps a sua atualizao.

66
Curso
Hibernate

Otimista: utilizar o controle otimista significa que se T1 l e


altera um dado ele no ser bloqueado durante o intervalo entre
a leitura e atualizao. Caso uma outra transao T2 tenha lido
esse mesmo dado antes de T1 o atualiz-lo tente alter-lo em
seguida na base de dados, um erro de violao de concorrncia
deve ser gerado.

15.1 LOCK OTIMISTA

Para ilustrar o gerenciamento do tipo otimista, um exemplo


dado a partir das Figura 22 e Figura 23.

O problema mostrado na Figura 22, onde, inicialmente, duas


transaes (ilustradas por Thread 1 e Thread 2) acessam um
mesmo dado na base de dados (SELECT Dado), uma seguida
da outra. Logo em seguida, a primeira transao (Thread 1)
atualiza este dado na base de dados e depois quem tambm o
atualiza a segunda transao (Thread 2). Nesta abordagem
otimista, acontece que a atualizao do dado feita pela
segunda transao sobrescreve a atualizao realizada pela
primeira, ou seja, a atualizao feita pela primeira transao
perdida.

Figura 22 - Loocking Otimista: Atualizao Sobrescrita

Para resolver o problema descrito anteriormente com a


abordagem otimista, pode-se utilizar o conceito de Version
Number, que um padro utilizado para versionar
numericamente os dados de uma linha de uma tabela na base
de dados. Por exemplo, na Figura 23, tambm, inicialmente,

67
Curso
Hibernate

duas transaes (ilustradas por App 1 e App 2) acessam um


mesmo dado na base de dados (SELECT Dado), uma seguida
da outra. Com isso, esse mesmo dado nas duas transaes so
rotulados com a verso atual dele na base de dados, no caso,
Verso 1. Logo em seguida, a segunda transao atualiza este
dado. Quando a atualizao vai ser feita, verificado se a
verso do dado na transao corresponde verso dele na
base de dados. Nesta primeira atualizao, a verso da
transao 1 e a da base de dados tambm. Como elas so
iguais, a atualizao efetivada e a verso do dado na base de
dados passa a ser a Verso 2. Por fim, a primeira transao vai
tambm atualizar este mesmo dado. Dessa forma, tambm
feita uma comparao entre as verses do dado na transao e
na base de dados. Neste caso, a verso na transao a 1 e
na base de dados 2, ou seja, as verses no correspondem.

Assim, um erro disparado e a atualizao desejada pela


primeira transao no concretizada, evitando que a
atualizao feita pela segunda transao no seja desfeita.

Figura 23 - Loocking Otimista: Abodargem com Version Number

Com o Hibernate, uma forma de utilizar o versionamento dos


dados utilizar a anotao @Version no mapeamento das
tabelas. Para exemplificar o seu uso, considera-se a classe
ContaCorrente presente na Listagem 83 que ser mapeada
para a tabela conta_corrente na base de dados. Dentre os
diversos atributos da classe t o atributo denominado versao
do tipo inteiro que ir guardar a verso atual das linhas da
tabela.

68
Curso
Hibernate

Listagem 83 - Classe de Domnio: ContaCorrente. Primeira Estratgia Locking


Otimista

A tabela conta_corrente tambm deve ter uma coluna para


onde esse atributo versao ser mapeado, como mostrado no
script de criao da tabela na Listagem 84. De acordo com o
mapeamento feito na classe ContaCorrente, toda vez que uma
determinada linha for atualizada na base de dados, a sua
coluna versao ser incrementada de uma unidade, indicando a
nova verso dos dados.

Listagem 84 - Script para a Criao da Tabela conta_corrente

Considerando o exemplo apresentado na Listagem 85, em que


um objeto ContaCorrente criado e persistido na base de
dados, observa-se o resultado presente na Figura 24 da

69
Curso
Hibernate

insero do mesmo como linha da tabela correspondente. No


caso, a linha foi inserida e a verso atual da mesma assumiu o
valor zero, correspondendo primeira verso.

Listagem 85 Persistindo Objeto com Atributo Version Number

Figura 24 - Resultado da Execuo do Cdigo Presente na Listagem 85

Caso a prxima operao seja uma atualizao do objeto que


corresponde a esta linha, como mostrado na Listagem 86,
verifica-se o resultado na Figura 25, onde os dados da conta
corrente foram atualizados. Tambm teve-se a coluna versao
sendo incrementada de uma unidade, atualizando a informao
de versionamento da linha da tabela.

Listagem 86 Atualizando Objeto com Atributo Version Number

70
Curso
Hibernate

Figura 25 - Resultado da Execuo do Cdigo Presente na Listagem 86

Outra forma de implementar o lock otimista utilizando o


atributo que representa a verso do dado como sendo do tipo
timestamp. Neste caso, a classe ContaCorrente do exemplo
anterior ao invs de ter um atributo inteiro para guardar a
verso do dado, teria uma atributo do tipo java.util.Date para
guardar o instante no tempo da ltima atualizao. Neste caso,
a classe de domnio com o mapeamento seria equivalente
mostrada na Listagem 87. Neste exemplo, a tabela
conta_corrente deve conter uma coluna do tipo timestamp
denominada data_ultima_atualizao.

Listagem 87 - Classe de Domnio: ContaCorrente. Segunda Estratgia Locking Otimista

71
Curso
Hibernate

Se a tabela no possuir uma coluna para guardar a verso do


dado ou a data da ltima atualizao, com Hibernate, h uma
outra forma de implementar o lock otimista, porm essa
abordagem s deve ser utilizada para objetos que so
modificados e atualizados em uma mesma sesso (Session).
Se este no for o caso, deve-se utilizar uma das duas
abordagens citadas anteriormente.

Com essa ltima abordagem, quando uma determinada linha


vai ser atualizada, o Hibernate verifica se os dados dessa linha
correspondem aos mesmos dados que foi recuperado. Caso
afirmativo, a atualizao efetuada. Para isso, no mapeamento
da tabela, deve-se utilizar o atributo optimisticLock =
OptimisticLockType.ALL da anotao
@org.hibernate.annotations.Entity (Alm da anotao
javax.persistence.Entity), como mostrado na Listagem 91.

Listagem 88 - Classe de Domnio: ContaCorrente. Terceira Estratgia


Locking Otimista

Dessa maneira, quando uma linha dessa tabela fosse


atualizada, o SQL equivalente gerado para a atualizao seria
como o exibido na Listagem 89. Neste exemplo, considera-se a
atualizao do saldo para R$ 1.500,00 de uma determinada
conta de saldo R$ 1.000,00.

72
Curso
Hibernate

Listagem 89 - Exemplo com Lockin Otimista: optimisticLock =


OptimisticLockType.ALL

15.2 LOCK PESSIMISTA

A estratgia de lock pessimista para proibir o acesso


concorrente a um mesmo dado da base de dados feita
bloqueando o mesmo at que a transao seja finalizada.

Alguns banco de dados, como o Oracle e PostgreSQL, utilizam a


construo SQL SELECT FOR UPDATE para bloquear o dado at
que o mesmo seja atualizado. O Hibernate fornece um conjunto
de modos de lock (constantes disponveis na classe LockMode)
que podem ser utilizados para implementar o lock pessimista.

Considerando o exemplo da Listagem 90, onde um determinado


aluno consultado na base de dados e tem seu nome
atualizado. Neste caso, no h um bloqueio ao dado, ento
qualquer outra transao pode acessar este mesmo dado
concorrentemente e modific-lo, de forma que poder ocorrer
uma incosistncia dos dados. Na Listagem 91, h um exemplo
de uso do lock pessimista para resolver este problema, bastando
passar a constante LockMode.UPGRADE como terceiro
argumento do mtodo get do objeto Session.

Listagem 90 - Exemplo de Transao sem Lock

Listagem 91 - Exemplo de Transao com Lock Pessimista:


LockMode.UPGRADE

73
Curso
Hibernate

O mtodo get do objeto Session pode receber como terceiro


argumento para implementar o lock pessimista as seguintes
constantes.

Lock.NONE: S realiza a consulta ao banco se o objeto


no estiver no cache1.

Lock.READ: Ignora os dados no cache e faz verificao de


verso para assegurar-se de que o objeto em memria
o mesmo que est no banco.

Lock.UPDGRADE: Ignora os dados no cache, faz


verificao de verso (se aplicvel) e obtm lock
pessimista do banco (se suportado).

Lock.UPDGRADE_NOWAIT: Mesmo que UPGRADE, mas


desabilita a espera por liberao de locks, e dispara uma
exceo se o lock no puder ser obtido. Caso especial do
Oracle que utiliza a clusula SELECT ... FOR UPDATE
NOWAIT para realizar locks.

Lock.WRITE: Obtida automaticamente quando o Hibernate


realiza alguma insero ou atualizao na base de dados.

16. CACHING

O cache uma tcnica comumente utilizada para aprimorar o


desempenho da aplicao no que diz respeito ao acesso ao banco de
dados. Com o cache possvel fazer uma cpia local dos dados,
evitando acesso ao banco sempre que a aplicao precise, por
exemplo, acessar dados que nunca ou raramente so alterados e dados
no crticos. O uso do cache no indicado para manipulao de dados
crticos, de dados que mudam freqentemente ou de dados que so
compartilhados com outras aplicaes legadas. Uma m escolha das
classes que tero objetos em cache pode gerar inconsistncias na base
de dados.

Existem trs tipos principais de chache:

Escopo de Transao: utilizado no escopo da transao, ou seja,


cada transao possui seu prprio cache. Duas transaes
diferentes no compartilham o mesmo cach.

Escopo de Processo: h o compartilhamento do cache entre uma


ou mais transaes. Os dados no escopo do cache de uma

74
Curso
Hibernate

transao podem ser acessados por uma outra transao que


executa concorrentemente, podendo provocar implicaes
relacionadas ao nvel de isolamento.

Escopo de Cluster: cache compartilhado por vrios processos


pertencentes a mquinas virtuais distintas e deve ser replicado
por todos os ns do cluster.

Considerando o cache no escopo da transao, se na transao


houver mais de uma consulta a dados com mesmas identidades de
banco de dados, a mesma instncia do objeto Java ser retornada.

Pode ser tambm que o mecanismo de persistncia opte por


implementar identidade no escopo do processo, de forma que a
identidade do objeto seja equivalente identidade do banco de
dados. Assim, se a consulta a dados em transaes que executam
concorrentemente for feita a partir de identificadores de banco de
dados iguais, o resultado tambm ser o mesmo objeto Java. Outra
forma de se proceder retornar os dados em forma de novos
objetos. Assim, cada transao teria seu prprio objeto Java
representando o mesmo dado no banco.

No escopo de cluster, necessrio haver comunicao remota, em


que os dados so sempre manipulados por cpias. Em geral, utiliza-
se o JavaGroups, que consiste em uma plataforma utilizada como
infra-estrutura para a sincronizao do cache no no cluster.

Nas situaes em que estratgias de MOR permitem que vrias


transaes manipulem uma mesma instncia de objeto persistente,
importante ter um controle de concorrncia eficiente, por exemplo,
bloqueando um dado enquanto ele no atualizado. Utilizando o
Hibernate, ter-se- um conjunto diferente de instncias para cada
transao, ou seja, tem-se identidade no escopo da transao.

16.1 ARQUITETURA DE CACHE COM HIBERNATE

A Figura 26 apresenta a arquiteura de cache com o Hibernate.


Existem dois nveis de caches. O primeiro nvel encontra-se em
nvel de uma sesso (Session), ou em nvel de transao de
banco de dados ou at mesmo de uma transao de aplicao.
Este nvel no pode ser desabilitado e garante a identifidade do
objeto dentro da sesso/transao. Dessa forma, dentro de
uma mesma sesso, garantida que se a aplicao requisitar o
mesmo objeto persistente duas vezes, ela receber de volta
mesma instncia, evitando um trfego maior na base de

75
Curso
Hibernate

dados.

Com o uso do cache em nvel de transao, nunca podero


existir diferentes representaes do mesmo registro de banco
de dados ao trmino de uma transao, tendo apenas um
objeto representando qualquer registro. Mudanas realizadas
em um objeto, dentro de uma transao, so sempre visveis
para qualquer outro cdigo executado dentro da mesma
transao.

Quando so feitas chamadas atravs dos mtodos: load(),


find(), list(), iterate() ou filter() o contedo do objeto
primeiramente procurado no nvel de cach.

O segundo nvel de cache opcional e pode abranger o nvel do


escopo do processo ou do cluster. um cache de estado e no
de instncias persistentes. Por ser opcional, preciso
configurar este nvel de cache para ser usado na aplicao.
Cada classe que precisar ter objetos em cache possui uma
configurao individual, pois cada uma ter particularidade de
mapeamento.

Figura 26 - Arquitetura de Cach

O Cache Provider utilizado para informar qual poltica de

76
Curso
Hibernate

cache de segundo nvel ser utilizada na aplicao. Essa


poltica definida no arquivo hibernate.cfg.xml a partir da
propriedade hibernate.cache.provider_class e pode assumir
algum dos valores abaixo:

EHCache (org.hibernate.cache.EhCacheProvider): usado


para o gerenciamento de caches no escopo do processo.
Possui uma boa documentao e fcil de configurar.
Alm disso, suporta cache de consultas que ser
apresentado na prxima sesso.

OSCache (org.hibernate.cache.OSCacheProvider): usado


para o gerenciamento de caches no escopo do processo
ou do cluster.

SwarmCache
(org.hibernate.cache.SwarmCacheProvider): usado para
o gerenciamento de caches no escopo do cluster. No
suporta cache de consultas.

JBossCache (org.hibernate.cache.TreeCacheProvider):
usado para o gerenciamento de caches no escopo do
cluster. um servio de replicao por cluster
transacional. Suporta cache de consultas.

16.2 MAPEANDO CACHE

Quando se utiliza o segundo nvel de cache, importante


utilizar uma estratgia para gerenciar o nvel de concorrncia
dos dados. A estratgia de concorrncia uma mediadora,
responsvel por armazenar e recuperar os dados no cache.
Com o Hibernate, possvel utilizar uma de quatro estratgias:

Transacional: utilizado em ambiente JTA (gerencivel) e


para manter dados em cache so mais consultados do
que atualizados. Garante o nvel de isolamento da
transao at o nvel repeatable-read, em que o valor
mantido durante toda a transao.

Leitura/Escrita (Read-Write): utilizada se a aplicao


precisar atualizar os dados que esto em cache. No
deve ser utilizada quando o nvel de isolamento da
transao for do tipo Serializable. Utilizado em
ambientes que no utilizam cluters.

77
Curso
Hibernate

Nonstrict Read-Write: utilizada se os dados em cache


dificilmente sejam atualizados, ou seja, se for quase que
improvvel duas transaes atualizarem o mesmo dado
simultaneamente. importante tambm a utilizao de
um nvel rgido de isolamento da transao. No garante
que o estado do cache seja sincronizado com o do banco
de dados.

Read-Only: utilizada se o cache for aplicado a dados da


aplicao que somente so lidos, ou seja, nunca so
modificados. Estratgia simples, segura em nvel de
escopo de cluster e apresenta melhor performance.

A Tabela 5 apresenta quais nveis de cache so suportados por


quais polticas de cach.

Tabela 5 Polticas X Nveis de Cach

78

Potrebbero piacerti anche