Você está na página 1de 30

Hibernate Associao

Caio Nakashima
caio.nakashima@mds.gov.br
caionakashima@gmail.com

Classe pessoa
import java.util.Calendar;
public class Pessoa {
private Long id;
private Calendar dataNascimento;
private String nome;
private char
sexo;
/** Creates a new instance of Pessoa */
public Pessoa() {}
public Long getId() {
return id;
}
private void setId(Long pId) {
this.id = pId;
}
public Calendar getDataNascimento() {
return dataNascimento;
}
public void setDataNascimento (Calendar pData){
this.dataNascimento = pData;
}
// ... Mtodos get e set
}

Arquivo de mapeamento Person.hbm.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Pessoa" table="PESSOA">
<id name="id" column="PES_ID">
<generator class="sequence"/>
</id>
<property name="dataNascimento"

column="PES_DATANASC"/>

<property name="nome" column="PES_NOME" not-null="true"/>


<property name="sexo" column="PES_SEXO"/>
</class>
</hibernate-mapping>

Arquivo de mapeamento hibernate


Adicionar novo mapeamento para a configurao do
Hibernate (hibernate.cfg.xml)

<mapping resource="Event.hbm.xml"/>
<mapping resource="Pessoa.hbm.xml"/>

Associao entre duas entidades


Ser criada associao entre duas entidades.
Pessoas podem participar de eventos e eventos
podem ter participantes.
As questes de projeto para serem gerenciados
so:
Direo, multiplicidade e comportamento de coleo

Uma associao unidirecional


Ser adicionados eventos para a classe Pessoa.
Por este caminho possvel navegar para os
eventos para uma pessoa em particular, sem
executar uma consulta explcita chamando o
mtodo aPessoa.getEvents().
Ser adicionado uma coleo de eventos para a
classe Pessoa.
Pode-se utilizar uma coleo Java (SET), porque a
coleo no contem elementos duplicados e a
ordem no relevante.
Assim ser projetada uma associao unidirecional
multi-valorado, implementado com um SET.
6

Alterao da classe Pessoa.java


public class Pessoa {
// Associando a um conjunto de eventos.
private Set events = new HashSet();
public Set getEvents() {
return events;
}
public void setEvents(Set events) {
this.events = events;
}
}

Para pensar
Antes de mapear esta associao, uma pequena
reflexo.
Esta uma associao unidirecional.
Pode-se criar outra coleo na classe Event, se
desejar navegar de forma bi-direcional,
Event.getParticipants().
Esta escolha de projeto fica a cargo do projetista,
que claro nesta discusso de multiplicidade da
associao, uma associao de muitos para muitos.

Hibernate's many-to-many mapping:


<hibernate-mapping>
<class name="Pessoa" table="PESSOA">
<id name="id" column="PES_ID">
<generator class="sequence"/>
</id>
<property name="dataNascimento"

column="PES_DATANASC"/>

<property name="nome" column="PES_NOME" notnull="true"/>


<property name="sexo" column="PES_SEXO"/>
<set name="events" table="PESSOA_EVENT">
<key column="PES_ID"/>
<many-to-many column="EVENT_ID" class="Event"/>
</set>
</class>

Tipos de Mapeamento
Hibernate suporta todos os tipos de mapeamento de
colees, um <set> o mais comum.
Para uma associao de muitos-para-muitos (ou uma
relaes entre entidades n:m), uma associao entre tabelas
necessria.
Cada linha desta tabela representa uma ligao entre uma
pessoa e um evento.
O nome da tabela configurado com o atributo da tabela de
um conjunto de elementos.
O identificador no nome da coluna em uma associao, para
o lado da pessoa definido com o elemento <key>, o nome
da coluna para o lado do evento com o atriburo coluna de
<many-to-many>.
necessrio informar o Hibernate a classe de objetos na
coleo (a classe de outro lado da referncia).
10

Mapeamento do Esquema

Events
event_id (PK)
event_date
title

Pessoa-Event
event_id
pes_id

Pessoa
pes_id
nome
sexo
datanasc

11

Trabalhando com associao


Novo mtodo em Main.java para associar pessoas a
eventos.
try{
sf = new
Configuration().configure("hibernate.cfg.xml").buildSessionFactor
y();
Session session = sf.openSession(); //Abre sesso
Transaction tx = session.beginTransaction(); //Cria transao
//Busca uma pessoa
Long pes_id = new Long(2);
Pessoa pessoa = (Pessoa) session.get(Pessoa.class, pes_id);
System.out.println("Pessoa "+pessoa.getNome());
//Busca uma evento
Long event_id = new Long(1);
Event evento = (Event) session.load(Event.class, event_id);
System.out.println("Evento "+evento.getTitle());
pessoa.getEvents().add(evento);
tx.commit(); //Fecha transao
12
session.close(); //Fecha sesso

load() X get()
http://forum.hibernate.org/viewtopic.php?p=2387456
O mtodo load() mais antigo que o mtodo
get().
Se o mtodo load() no encontrar o objeto no cache
ou banco de dados uma exceo gerada.
O mtodo load() nunca retorna NULL. O mtodo
get() retorna NULL se o objeto no for encontrado.
Depois de carregar uma Pessoa (pessoa) e um
Evento (event), adiciona-se o evento para a
pessoa.
No existe comando explcito de UPDATE() ou
SAVE().

automatic dirty checking


Hibernate detecta automaticamente a coleo que
foi modificado e a necessidade de ser salvo.
Isto denominado automatic dirty checking, e
pode-se observar isto tambm tentando modificar o
nome e data de qualquer objeto.
Como os dados esto em estado de persistncia,
Hibernate monitora qualquer mudana e executa
SQL em background.
O processo de sincronizao do estado da memria
com o banco de dados, termina com a finalizao
da unidade de trabalho. Este processo
denominado FLUSHING.
14

Persistncia
Pode-se carregar um pessoa ou evento para uma
diferente unidade de trabalho.
Pode-se modificar um objeto fora de uma seo,
quando no est em estado de persistncia (se tiver
sido persistido antes da seo ser chamada).

15

Associao
O exemplo apresentado foi de uma associao entre duas
classes com mesmo grau de importncia, duas entidades.
Existem outras classes e tipos que podem ser classificados
como menos importantes.
Denomina-se estas classes do tipo valores (value types) e
suas instncias dependem de uma entidade em particular.
As instncias destes tipos no possuem sua prpria
entidade, nem so divididos entre entidades.
Os tipos de valores no podem ser encontrado somente no
JDK, mas podem tambm ser escritos dependentes da
classe, Endereo ou Saldo, etc.
Hibernate considera todos os tipos do JDK como tipo de valores.

16

Coleo de valores
Adiciona-se uma coleo de tipos de valores para uma
entidade Pessoa.
Deseja-se armazenar endereo de email, assim o tipo
utilizado String e a coleo novamente um Set.
private Set email = new HashSet();
public Set getEmail () {
return email;
}
public void setEmail (Set email) {
this.email = email;
}

Mapeamento
<set name="email" table=PESSOA_EMAIL">
<key column="PES_ID"/>
<element type="string" column="EMAIL"/>
</set>
17

A diferena comparando com o mapeamento


anterior um elemento a parte, que especifica o
Hibernate que a coleo no contm referncia a
outra entidade, mas uma coleo de elementos do
tipo String (o nome em letras minsculas especifica
um mapeamento Hibernate tipo/converso).
Novamente, o atributo <table> de um conjunto de
elementos do nome da tabela para a coleo.
O elemento <key> define a coluna de chave
estrangeira da tabela de coleo.
A coluna <attribute> define o nome da coluna onde
os valores String esto armazenados.
18

Esquema com a tabela EMAIL


Events
event_id (PK)
event_date
title

Pessoa-evento
event_id
pess_id

Pessoa
pes_id
nome
datanasc
sexo

Pessoa_email
pess_id
email
19

A chave primria da tabela composta pelos


valores das duas colunas (pess_id, email).
Isto implica que no pode ser duplicado email por
pessoa, que exatamente a semntica necessria
para um conjunto em Java.
Exerccio:
Inserir elementos nesta coleo.
Tentar repetir email para a mesma pessoa.

20

Associao Bi direcional
O exemplo de associao bi-direcional ser entre
pessoa (Pessoa) e trabalho no evento.
O esquema do banco de dados no muda, ainda
existir a multiplicidade de muitos-para-muitos.
Um banco de dados mais flexvel que uma
linguagem de programao distribuda
No necessita nada como uma direo de navegao
Dados podem ser visualizados e recuperados em
qualquer caminho possvel.

21

Coleo de participantes do evento


private Set participants = new HashSet();
public Set getParticipants() {
return participants;
}
public void setParticipants(Set participants) {
this.participants = participants;
}

Coleo de participantes do evento


<set name="participants" table="PESSOA_EVENT" lazy="true"
inverse="false">
<key column="EVENT_ID"/>
<many-to-many column="PERSON_ID" class="Person"/>
</set>
22

inverse
Esse atributo utilizado para que o Hibernate saiba
como tratar a associao entre duas tabelas.
Quando um lado da associao define o atributo
inverse como true, indica que a ligao do
relacionamento entre a associao ser de
responsabilidade do "outro lado" da associao.
Se o atributo inverse no for definido como true, o
Hibernate no tem como saber qual dos dois lados
foi atualizado, ou seja, vai sempre atualizar os dois
lados de uma vez, uma atualizao para cada
classe da relao, o que seria desnecessrio.
Caso contrrio, o Hibernate passa a saber de qual
lado fazer a atualizao e fazendo uma nica vez.
23

lazy
Considerando o problema:
quando se realiza uma consulta (select) em um objeto
Pessoa implica em serem feitos n (quantidade de emails
da Pessoa) outras consultas para buscar os seus emails.

A resoluo do problema pode ser feita apenas


definindo o atributo lazy como sendo true. A
coleo de centros passa a ser lazy-loading, o que
significa que somente ser recuperada quando
solicitada, ou seja, a coleo de emails de uma
Pessoa s seria solicitada caso o programador a
acesse atravs da chamada ao mtodo getEmail().
24

Mapeamento n-1
<many-to-one name="propertyName"
class="ClassName" column="column_name"
fetch="join|select" update="true|false" lazy="true|
false"
insert="true|false" cascade="all|none|save-update|
delete />

25

Atributos do mapeamento n-1


name: nome do atributo na classe Java;
column: coluna do banco de dados. uma chave
estrangeira;
class: nome da classe Java da entidade relacionada;
insert e update: indica se o atributo ser includo e alterado
ou somente lido;
fetch: se definido como join usado para realizar joins sem
restrio de nulidade (outer-join). Se for select, um novo
select feito para recuperar a informao da associao.
lazy: se igual a true, o objeto s ser recuperado se
solicitado; se igual a false, o objeto sempre ser recuperado.

26

cascade
indica com que ao em cascata o relacionamento ser tratado
none: associao ignorada;
save-update:os objetos associados vo ser inseridos ou
atualizados automaticamente quando o objeto "pai" for
inserido ou atualizado;
delete: os objetos associados ao objeto "pai" vo ser
deletados;
all: juno de delete e save-update;
all-delete-orphan: o mesmo que all, mas o Hibernate deleta
qualquer objeto que tiver sido retirado da associao;
delete-orphan: se o objeto no fizer mais parte da
associao, ele removido.
27

fetch: se definido como join usado para realizar


joins sem restrio de nulidade (outer-join). Se for
select, um novo select feito para recuperar a
informao da associao.
lazy: se igual a true, o objeto s ser recuperado se
solicitado; se igual a false, o objeto sempre ser
recuperado.

28

Exerccio
Considerando do Diagrama da prxima transparncia e
utilizando a camada de persistncia Hibernate elaborar um
conjunto de arquivos necessrios para criar as tabelas,
inserir, alterar, excluir e listar os registros das seguintes
entidades:
Entidade
Event
Pessoas
Pessoa_email
Pessoa_telefones

Criar
Sim
Sim
Sim
Sim

Inser.
Sim
Sim
Sim
Sim

Excl.
Sim
Sim
Sim
Sim

Alter.
Sim
Sim
Sim
Sim

Listar
+ pessoas
+ email + tel
+ pessoas

Palestras

Sim

Sim

Sim

Sim

+ pessoas
29

Exerccio
Pessoa

Events
1
n
Palestra
palestra_id
tema
titulo

event_id (PK)
event_date
title

n
n
1

pes_id
nome
datanasc
sexo
1

n
n

Pessoa_telefones

Pessoa_email

pess_id
telefone
Tipo (celular,
Residencial, etc.)

pess_id
email

30