1 / 30

Hibernate Associação

Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com. Hibernate Associação. Classe pessoa. import java.util.Calendar; public class Pessoa { private Long id; private Calendar dataNascimento; private String nome; private char sexo;

rufin
Télécharger la présentation

Hibernate Associação

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

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

  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>

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

  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

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

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

  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.

  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>

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

  11. Events event_id (PK) event_date title Pessoa-Event event_id pes_id Pessoa pes_id nome sexo datanasc Mapeamento do Esquema

  12. Trabalhando com associação • Novo método em Main.java para associar pessoas a eventos. 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 }

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

  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.

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

  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.

  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; } • Mapeamento <set name="email" table=“PESSOA_EMAIL"> <key column="PES_ID"/> <element type="string" column="EMAIL"/> </set>

  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.

  19. Events event_id (PK) event_date title Pessoa-evento event_id pess_id Pessoa pes_id nome datanasc sexo Pessoa_email pess_id email Esquema com a tabela EMAIL

  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.

  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.

  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; } • Coleção 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>

  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.

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

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

  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.

  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.

  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.

  29. Entidade Criar Inser. Excl. Alter. Listar Event Sim Sim Sim Sim + pessoas Pessoas Sim Sim Sim Sim + email + tel Pessoa_email Sim Sim Sim Sim + pessoas Pessoa_telefones Sim Sim Sim Sim Palestras Sim Sim Sim Sim + pessoas 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:

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

More Related