Transcript Associação Hibernate
Hibernate Associação
Caio Nakashima [email protected]
1
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; } // ... Métodos get e set } 2
Arquivo de mapeamento Person.hbm.xml
Arquivo de mapeamento hibernate
• Adicionar novo mapeamento para a configuração do Hibernate (hibernate.cfg.xml)
Associação entre duas entidades
• Será criada associação entre duas entidades.
• Pessoas podem participar de eventos e eventos podem ter participantes.
• As questões de projeto para serem gerenciados são: – Direção, multiplicidade e comportamento de coleção
5
Uma associação unidirecional
• Será adicionados eventos para a classe
Pessoa
.
• Por este caminho é possível navegar para os eventos para uma pessoa em particular, sem executar uma consulta explícita chamando o método
aPessoa.getEvents()
.
• Será adicionado uma coleção de eventos para a classe
Pessoa.
• Pode-se utilizar uma coleção Java (SET), porque a coleção não contem elementos duplicados e a ordem não é relevante.
• Assim será projetada uma associação unidirecional multi-valorado, implementado com um SET.
6
Alteração 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; } } 7
Para pensar
• Antes de mapear esta associação, uma pequena reflexão.
• Esta é uma associação unidirecional.
• Pode-se criar outra coleção na classe
Event
, se desejar navegar de forma bi-direcional,
Event.getParticipants()
.
• Esta escolha de projeto fica a cargo do projetista, que é claro nesta discussão de multiplicidade da associação, uma associação de muitos para muitos.
8
Hibernate's many-to-many mapping:
Tipos de Mapeamento
• Hibernate suporta todos os tipos de mapeamento de coleções, um
é o mais comum.
• Para uma associação de muitos-para-muitos (ou uma relações entre entidades n:m), uma associação entre tabelas é necessária.
• Cada linha desta tabela representa uma ligação 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 associação, para o lado da pessoa é definido com o elemento
, o nome da coluna para o lado do evento com o atriburo coluna de
• É necessário informar o Hibernate a classe de objetos na coleção (a classe de outro lado da referência).
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 associação
• Novo método em Main.java para associar pessoas a eventos.
try{ sf = new Configuration().configure("hibernate.cfg.xml").buildSessionFactor
y(); Session session = sf.openSession(); //Abre sessão Transaction tx = session.beginTransaction(); //Cria transação //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 transação session.close(); //Fecha sessão 12 }
load() X get()
• http://forum.hibernate.org/viewtopic.php?p=2387456 •
O método load() é mais antigo que o método get().
• Se o método load() não encontrar o objeto no cache ou banco de dados uma exceção é gerada.
• O método load() nunca retorna NULL. O método get() retorna NULL se o objeto não for encontrado.
• Depois de carregar uma Pessoa (
pessoa
) e um Evento
(event),
adiciona-se o evento para a pessoa.
• Não existe comando explícito de UPDATE() ou SAVE().
automatic dirty checking
• Hibernate detecta automaticamente a coleção que foi modificado e a necessidade de ser salvo.
• Isto é denominado
automatic dirty checking,
e pode se observar isto também tentando modificar o nome e data de qualquer objeto.
• Como os dados estão em estado de persistência, Hibernate monitora qualquer mudança e executa SQL em background.
• O processo de sincronização do estado da memória com o banco de dados, termina com a finalização da unidade de trabalho. Este processo é denominado
FLUSHING.
14
Persistência
• Pode-se carregar um pessoa ou evento para uma diferente unidade de trabalho.
• Pode-se modificar um objeto fora de uma seção, quando não está em estado de persistência (se tiver sido persistido antes da seção ser chamada).
15
Associação
• O exemplo apresentado foi de uma associação entre duas classes com mesmo grau de importância, 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 instâncias dependem de uma entidade em particular.
• As instâncias destes tipos não possuem sua própria entidade, nem são divididos entre entidades. • Os tipos de valores não podem ser encontrado somente no JDK, mas podem também ser escritos dependentes da classe, Endereço ou Saldo, etc.
– Hibernate considera todos os tipos do JDK como tipo de valores.
16
Coleção de valores
• Adiciona-se uma coleção de tipos de valores para uma entidade
Pessoa.
• Deseja-se armazenar endereço de email, assim o tipo utilizado é String e a coleção é novamente um Set.
private Set email = new HashSet(); public Set getEmail () { return email; } public void setEmail (Set email) { this.email = email; }
• Mapeamento
• A diferença comparando com o mapeamento anterior é um elemento a parte, que especifica o Hibernate que a coleção não contém referência a outra entidade, mas uma coleção de elementos do tipo String (o nome em letras minúsculas especifica um mapeamento Hibernate tipo/conversão).
• Novamente, o atributo <
table
> de um conjunto de elementos do nome da tabela para a coleção.
• O elemento
define a coluna de chave estrangeira da tabela de coleção.
• A coluna <
attribute
> define o nome da coluna onde os valores String estão 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 primária da tabela é composta pelos valores das duas colunas
(pess_id, email)
.
• Isto implica que não pode ser duplicado email por pessoa, que é exatamente a semântica necessária para um conjunto em Java.
• Exercício: – Inserir elementos nesta coleção.
• Tentar repetir email para a mesma pessoa.
20
Associação Bi direcional
• O exemplo de associação bi-direcional será entre pessoa (Pessoa) e trabalho no evento.
• O esquema do banco de dados não muda, ainda existirá a multiplicidade de muitos-para-muitos.
• Um banco de dados é mais flexível que uma linguagem de programação distribuída – Não necessita nada como uma direção de navegação – Dados podem ser visualizados e recuperados em qualquer caminho possível.
21
• Coleção de participantes do evento
private Set participants = new HashSet(); public Set getParticipants() { return participants; } public void setParticipants(Set participants) { this.participants = participants; }
• Coleção de participantes do evento
inverse
• Esse atributo é utilizado para que o
Hibernate
como tratar a associação entre duas tabelas. saiba • Quando um lado da associação define o atributo
inverse
como
true
, indica que a ligação do relacionamento entre a associação será de responsabilidade do "outro lado" da associação.
• Se o atributo
inverse Hibernate
não for definido como
true
, o não tem como saber qual dos dois lados foi atualizado, ou seja, vai sempre atualizar os dois lados de uma vez, uma atualização para cada classe da relação, o que seria desnecessário. • Caso contrário, o
Hibernate
passa a saber de qual lado fazer a atualização 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 resolução do problema pode ser feita apenas definindo o atributo
lazy
como sendo
true
. A coleção de centros passa a ser
lazy-loading
, o que significa que somente será recuperada quando solicitada, ou seja, a coleção de emails de uma Pessoa só seria solicitada caso o programador a acesse através da chamada ao método getEmail().
24
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á incluído e alterado ou somente lido; fetch: se definido como join é usado para realizar joins sem restrição de nulidade ( outer-join ). Se for select , um novo select é feito para recuperar a informação da associação. lazy: se igual a true , o objeto só será recuperado se solicitado; se igual a false , o objeto sempre será recuperado. 26 • • • • • • indica com que ação em cascata o relacionamento será tratado none : associação é ignorada; save-update :os objetos associados vão ser inseridos ou atualizados automaticamente quando o objeto "pai" for inserido ou atualizado; delete : os objetos associados ao objeto "pai" vão ser deletados; all : junção de delete e save-update ; all-delete-orphan : o mesmo que all , mas o Hibernate deleta qualquer objeto que tiver sido retirado da associação; delete-orphan : se o objeto não fizer mais parte da associação, ele removido. 27 • fetch: se definido como join é usado para realizar joins sem restrição de nulidade (outer-join). Se for select, um novo select é feito para recuperar a informação da associação. • lazy: se igual a true, o objeto só será recuperado se solicitado; se igual a false, o objeto sempre será recuperado. 28 • Considerando do Diagrama da próxima transparência e utilizando a camada de persistência Hibernate elaborar um conjunto de arquivos necessários 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 n Palestra palestra_id tema titulo 1 Events event_id (PK) event_date title n n n Pessoa_telefones pess_id telefone Tipo (celular, Residencial, etc.) n 1 Pessoa n pes_id nome datanasc sexo 1 n Pessoa_email pess_id email 30Atributos do mapeamento n-1
cascade
Exercício
Exercício