1 Hibernate Associação Caio Nakashima [email protected] [email protected].

30
1 Hibernate Associação Caio Nakashima [email protected] [email protected]

Transcript of 1 Hibernate Associação Caio Nakashima [email protected] [email protected].

Page 1: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

1

Hibernate Associação

Caio Nakashima

[email protected]

[email protected]

Page 2: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

2

Classe pessoaimport 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}

Page 3: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

3

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>

Page 4: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

4

Arquivo de mapeamento hibernate

• Adicionar novo mapeamento para a configuração do Hibernate (hibernate.cfg.xml)

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

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

Page 5: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

5

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

Page 6: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

6

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.

Page 7: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

7

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;

}

}

Page 8: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

8

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.

Page 9: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

9

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>

Page 10: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

10

Tipos de Mapeamento• Hibernate suporta todos os tipos de mapeamento de

coleções, um <set> é 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 <key>, o nome da coluna para o lado do evento com o atriburo coluna de <many-to-many>.

• É necessário informar o Hibernate a classe de objetos na coleção (a classe de outro lado da referência).

Page 11: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

11

Mapeamento do Esquema

Events

event_id (PK)event_datetitle

Pessoa-Event

event_idpes_id

Pessoa

pes_idnomesexodatanasc

Page 12: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

12

Trabalhando com associação

try{ sf = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory(); 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 }

• Novo método em Main.java para associar pessoas a eventos.

Page 13: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

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().

Page 14: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

14

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.

Page 15: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

15

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).

Page 16: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

16

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.

Page 17: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

17

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

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

• Mapeamento

Page 18: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

18

• 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 <key> 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.

Page 19: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

19

Esquema com a tabela EMAIL

Events

event_id (PK)event_datetitle

Pessoa-evento

event_idpess_id

Pessoa

pes_idnomedatanascsexo

Pessoa_email

pess_idemail

Page 20: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

20

• 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.

Page 21: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

21

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.

Page 22: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

22

• Coleção de participantes do evento

private Set participants = new HashSet();

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

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

• Coleção de participantes do evento

Page 23: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

23

inverse

• Esse atributo é utilizado para que o Hibernate saiba como tratar a associação entre duas tabelas.

• 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 não for definido como true, o Hibernate 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.

Page 24: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

24

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().

Page 25: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

25

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“ />

Page 26: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

26

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á 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.

Page 27: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

27

cascade

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.

Page 28: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

28

• 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.

Page 29: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

29

Exercício

• 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:

+ pessoasSimSimSimSimPalestras

SimSimSimSimPessoa_telefones

+ pessoasSimSimSimSimPessoa_email

+ email + telSimSimSimSimPessoas

+ pessoasSimSimSimSimEvent

ListarAlter.Excl.Inser.CriarEntidade

Page 30: 1 Hibernate Associação Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

30

Exercício

Events

event_id (PK)event_datetitle

Pessoa

pes_idnomedatanascsexo

Pessoa_email

pess_idemail

Pessoa_telefones

pess_idtelefoneTipo (celular, Residencial, etc.)

n n

nn

1

1

Palestra

palestra_id

tematitulo

n

nn

1