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 }
2

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>


3

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" not-null="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> </hibernate-mapping>
9

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 session.close(); //Fecha sesso 12 }

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 pes_id nome datanasc sexo

Pessoa-evento event_id pess_id

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|saveupdate|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 Palestras Criar Sim Sim Sim Sim Sim Inser. Sim Sim Sim Sim Sim Excl. Sim Sim Sim Sim Sim Alter. Sim Sim Sim Sim Sim Listar + pessoas + email + tel + pessoas + pessoas
29

Exerccio
Events 1 n Palestra palestra_id tema titulo n n Pessoa_telefones pess_id telefone Tipo (celular, Residencial, etc.) n Pessoa_email pess_id email event_id (PK) event_date title Pessoa n n n 1 pes_id nome datanasc sexo 1

30

Você também pode gostar