Luiz Carlos d´Oleron [email protected] SJCP Java Avançado Hibernate II.

45
Luiz Carlos d´Oleron [email protected] SJCP Java Avançado Hibernate II

Transcript of Luiz Carlos d´Oleron [email protected] SJCP Java Avançado Hibernate II.

Page 1: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´[email protected]

SJCP

Java Avançado

Hibernate II

Page 2: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Hibernate• Continuaremos a conhecer os conceitos básicos de hibernate

• Compreenderemos os conceitos técnicos que fomos apresentados na aula anterior

• E seremos apresentados a novos conceitos

• Devido a carga horária reduzida, veremos apenas uma parte importante de Hibernate. Fique atento à bibliografia no fim da apresentação|!

• Manter em mente que hibernate é uma ferramenta para simplificar a persistência de aplicações orientadas a objetos em Java

• Dessa forma, precisaremos conceber o sistema corretamente, senão hibernate não terá valia

Page 3: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Hibernate e DAO Pattern• Pergunta: Com hibernate, continuamos precisando do DAO

Pattern?

• Sim. Hibernate é uma camada de persistência que deve se encaixar acima de JDBC e abaixo do DAO

• DAO deve encapsular do resto do sistema que a tecnologia de persistência utilizada é hibernate

• Código hibernate não deve ser distribuído, em hipótese alguma, em regiões acima do DAO

• Manter em mente que estas subdivisões são lógicas, sendo, muitas vezes, os componentes de diferentes camadas, armazenados fisicamente no mesmo computador

Page 4: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

POJOs

• Hibernate fará a persistência de Objetos Java, em particular, Hibernate fará persistência de POJO´s

• Mais o que é um POJO?

• Como eu posso criar um POJO?

• POJO´s são formas de representar dados em objetos java

• Exemplo: classe Cliente

Page 5: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

POJOs

• Plain Old Java Objects

• Parecidos com JavaBeans

• Nome dado ao Objetos de Dados construídos com o velho padrão get/set

• Diferente de Javabeans, não precisam ser serializáveis (nem tem qualquer outra restrição sobre extrender uma classe específica ou mesmo implementar determinada interface)

Page 6: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Identificando um POJO

• Existem algumas relações de interesse entre os objetos:

– Igualdade• Dois objetos são iguais pelo operador “==”

– Equivalência• Dois objetos são equivalente através do método equals

– Identidade• Dois objetos possuem o mesmo valor de chave primária

Page 7: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Métodos equals e hashcode• Toda classe possui o método equals, com a assinatura a seguir:

public boolean equals(Object obj);

• Se a classe não definir um método equals, ela herdará o equals de Object (ou da superclasse)

• O método equals de Object utiliza apenas a igualdade pelo operador “==”

• Visto que dois objetos podem ser equivalentes mesmo não sendo a mesma instância, é comum que se sobre escreva o método equals de object

• Isto pode ser importante especialmente quando utilizamos coleções, visto que, por exemplo, muitas implementações do método java.util.Collection.contains(Object), chamam o método equals.

• Mas como isto deve ser feito?

• E o que o método hashcode tem haver com isso?

Page 8: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Contrato do método equals

– equals implementa uma relação de equivalência para referências não nulas:

• Reflexivo: x.equals(x) deverá retorna true• Simétrico: x.equals(y) é true se somente se y.equals(x) é

true• Transitivo: Se x.equals(y) é true e y.equals(z) é true, então

x.equals(z) é true• Consistência: Múltiplas invocações de x.equals(y) deverão

retornar sempre true ou sempre false desde que x e y não se alterem

• Para x não nulo, x.equals(null) deverá retornar false.

– Quando se reescrever o método equals, deverá se reescrever o método hashcode

Page 9: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Implementando o equals

Page 10: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Contrato do método hashcode

• Utilizado em estruturas do tipo Hash, como java.util.Hashtable.

• O nº de hash deve permanecer igual para chamadas sucessivas, desde que o estado do objeto se mantenha o mesmo.

• Se dois objetos são equivalentes, pelo método equals, eles devem produzir o mesmo valor para hashcode

• Se dois objetos são diferentes, pelo método equals, eles podem retornar hashcodes diferentes ou iguais

• O hashcode implementado por Object produz valores diferentes para diferentes objeto (pelo equals de object), normalmente fazendo isso através de uma representação inteira da referência de Object.

Page 11: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Implementando o hashcode

Page 12: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Relacionamentos e Mapeamentos

• Objetos se relacionam de várias formas

• Representar todos os tipos de relacionamentos possíveis entre objetos é uma das tarefas mais árduas de ORM

• Em hibernate, os relacionamentos são representados pelas estruturas das classes e seus respectivos mapeamentos

• Neste curso, veremos os seguintes tipos de relacionamentos, com seus respectivos mapeamentos:

– Um para Muitos

– Um para Um

– Muitos para Muitos

– Hierarquia de classes

– Relacionamentos bidirecionais

Page 13: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Associação Um para Muitos

• É o tipo mais simples de associação

• É o tipo mais comum de associação também

• Utilizados em agregações e composições

Page 14: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Associação Um para Muitos

Na classe Cliente, a associação unidirecional é representada por:

•um atributo Set de telefones•seus respectivos métodos acessores

•No mapeamento, definimos um set•Observe que usamos a tag one-to-many

Page 15: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

inverse=“true|false”• O atributo inverse=“false” indica que a classe tem

responsabilidade de gerenciar a associação e as instâncias que estão nelas.

• No mapeamento anterior, a responsabilidade de gerenciar a associação e persistir as alterações dos objetos envolvidos é das instâncias de Cliente, e não de Telefone

• O atributo inverse=“true” indica que a responsabilidade de gerenciar a associação é do lado oposto da associação

Page 16: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

cascade

• Hibernate permite a persistência transitiva• Isto é feito quando você chama uma operação, tipo

save, em um objeto, sendo a operação propagada nos demais objetos associados

• Isto é feito com cascade• Cascade define quais operações serão propagadas nos

objetos associados• Alguns dos valores possíveis são:

– all– none– save-update– delete– all-delete-orphan

Page 17: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Associação um para um• O mapeamento um para um é tão

simples (ou mais) que o mapeamento um-para-muitos

• O mapeamento de Endereco é simples, como em Telefone

• O mapeamento de Cliente possui agora a tag one-to-one

• Lembre-se de adicionar o mapeamento de Endereco ao hibernate.cfg.xml

Page 18: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Associação muito para muitos

• Tente não usar associações muito para muitos

• Observe sempre se a relação não poderia ser desmembrada com uma entidade de relacionamento e duas associações do tipo um-para-muitos (Pattern Mediator)

• Uma instância simples de associação muitos-para-muitos é a associaçao muitos-para-muitos unidirecional

• Ela se parece bastante com o que já foi visto até agora:

<set name=“categorias” table=“tab_categoria_cliente” cascade=“save-update”>

<key column=“id_cliente”/>

<many-to-many class=“Categoria” column=“id_categoria”/>

</set>

Page 19: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Associação muito para muitos

Page 20: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Associações bidirecionais

• No exemplo visto até aqui, os clientes “conhecem” seus telefones, mas uma instância de telefone não possui nenhuma informação sobre seu proprietário

• A este tipo de associação, damos o nome de associação unidirecional

• Muitas vezes, é necessário representar uma associação bidirecional, aonde ambas as extremidades da associação tem conhecimento da outra

• Associações bidirecionais são mais difíceis de manter, visto que ambos os lados precisam sincronizar as alterações, quando elas ocorrem

Page 21: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Associações bidirecionaisNuma associação Bidirecional, ambos os lados tem que ser

notificados, quando de uma alteração:

class Cliente{private Set<Categoria> categorias;...

}class Categoria{

private Set<Cliente> clientes;...

}...cliente.getCategorias().add(categoria);categoria.getClientes().add(cliente);...

Page 22: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Associações bidirecionaisOs mapeamentos das classes:

<class name=“Cliente” table=“tab_clientes”>

...<set name=“categorias”>

<key column=“codigo_cliente”> <many-to-many class=“Categoria” column=“codigo_categoria”/></set>...

</class>

<class name=“Categoria” table=“tab_catergoria”>

...<set name=“clientes” inverse=“true” >

<key column=“codigo_categoria”> <many-to-many class=“Cliente” column=“codigo_cliente”/></set>...

</class>

Page 23: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Representando Herança

• Mapear herança é um dos trabalhos mais difíceis em ORM

• Isto por que não existe herança no mundo relacional

• Assim sendo “herança é o descasamento mais visível entre os mundos relacional e orientado a objetos”

Page 24: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Estratégias para Herança• Existem três estratégias para se trabalhar com herança:

– Tabela por classe concreta

– Tabela por hierarquia de classe

– Tabela por Subclasse

• Cada estratégia possui suas próprias vantagens e desvantagens

• Às vezes você já possui uma estrutura de banco de dados legada, e terá que usar a estratégia que melhor se adeqüe a este legado

Page 25: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Tabela por Classe concreta

• Ideal para classes que não fazem parte de uma hierarquia ou que estão na raiz de uma hierarquia (nível mais alto)

– Essas classes não devem ser usadas em polimorfismo

– Uma declaração <class> para cada classe concreta; um atributo table diferente para cada uma (igual a mapeamento simples)

• Desvantagens

– Pouco suporte para associações polimórficas

– Queries polimórficos, executados em superclasses das classes usadas causam múltiplos queries nas tabelas mapeadas às classes concretas

– Dificulta evolução do esquema (mudanças semânticas em propriedades da superclasse afetam colunas de várias tabelas)

Page 26: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Tabela por Classe concreta

•Nessa estratégia, cada mapeamento se comporta como uma classe isolada, não tendo nenhum conhecimento do resto da hierarquia

Page 27: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Tabela por hierarquia de classe

• Mapeia-se a hierarquia toda a uma única tabela– Tabela inclui uma coluna para identificar a classe (tipo); esta

coluna (discriminator) não é mapeada a uma propriedade mas usada internamente pelo Hibernate

– Há colunas para todas as propriedades de todas as classes da hierarquia

– A classe raiz é mapeada da forma convencional <class>– Subclasses são mapeadas dentro de <class> como

<subclass>

Page 28: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Tabela por hierarquia de classe

<hibernate-mapping> <class name=“Cliente" table=“tab_clientes" discriminator-value="BD">

<id name=“codigo"> <generator class="native"/> </id>

<discriminator column="tipo_cliente" type="string"/>

<property name=“nome"/> ...

<subclass name="ClientePessoaFisica" discriminator-value=“cfisica">

<property name=“cpf"/> ... </subclass><subclass name="ClientePessoaJuridica"

discriminator-value=“cjuridica"> <property name=“cnpj"/> ... </subclass>

... </class></hibernate-mapping>

Vantagens• Forma mais eficiente de

implementar polimorfismo• É simples de implementar,

entender e evoluir

Desvantagens• Colunas de propriedades

declaradas em subclasses precisam aceitar valores nulos (não pode ser declarada not-null)

• Adeus normalização de base de dados!

Page 29: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Tabela por Subclasse

• Representa herança como relacionamentos de chave estrangeira

– Cada subclasse que declara propriedades persistentes (inclusive interfaces e classes abstratas) tem sua própria tabela

– Cada tabela possui colunas apenas para propriedades não-herdadas, e uma chave primária que é chave estrangeira da superclasse

– Criação de uma instância cria registros nas tabelas da superclasse e subclasse

– A recuperação dos dados é realizada através de um join das tabelas

– <joined-subclass> (que pode conter outros elementos <joined-subclass>) pode ser usada no lugar de ou dentro de <class>

Page 30: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Tabela por Subclasse

Page 31: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Tabela por Subclasse<hibernate-mapping> <class name=“Cliente" table=“tab_clientes">

<id name=“codigo"> <generator class="native"/> </id>

<property name=“nome"/> ...

<joined-subclass name="ClientePessoaFisica" table=“tab_cliente_ p_fisica”>

<key column=“codigo”/>

<property name=“cpf"/> <property name=“aniversario"/>

</ joined-subclass >

...

</class></hibernate-mapping>

Page 32: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Tabela por Subclasse

• Vantagens– Modelo relacional normalizado– Evolução e restrições de integridade simples– Novas classes/tabelas criadas sem afetar

classes/tabelas existentes

• Desvantagens– Performance baixa em hierarquias complexas– Mais difícil de codificar a mão (complicado de integrar

com JDBC legado)

Page 33: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Obtendo Objetos

• O modo mais simples de obter um objeto é através do método get da interface Session:

Long id = new Long(10);

Cliente cliente = (Cliente)session.get(Cliente.class, id);

Page 34: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

HQL e QBC• Na maioria das vezes, precisamos obter não só uma

única instância, mas necessitamos de grafos completos de Objetos

• por exemplo, podemos querer resgatar coleções de objetos que compartilham propriedades comuns

• Ou às vezes não conhecemos a chave primária de um objeto que desejamos, mas conhecemos outros valores os quais podem identificá-lo

• Nestes casos, podemos usar consultas com HQL (Hibernate Query Language) ou QBC (Query by Criteria)

Page 35: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Hibernate Query Language

• HQL é um dialeto orientado a objetos

• Baseado em SQL

• Só é usado para obtenção de objetos

• Não serve para alterar, excluir ou criar objetos

Page 36: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Exemplo HQL

Query q = session.createQuery(“FROM Cliente cliente WHERE cliente.name =:fname”);

q.setString(“fname”,”Luiz”);

List result = q.list();

Page 37: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Exemplo HQL

Podemos usar outros recursos:

Query q = session.createQuery(“FROM Cliente cliente WHERE cliente.name LIKE :fname ORDER BY cliente.cpf DESC”);

q.setString(“fname”,”Luiz”);List result = q.list();

Page 38: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Consultas e hierarquia de classe

• Polimorfismo é um mecanismo muito importante para o paradigma orientado a objetos

• Hibernate encapsula a maioria dos detalhes da transformação relacional-objeto

• Dessa forma, fazer uma consulta para tipos polimórficos é tão simples quanto para fazê-lo quando não há hierarquia de classes envolvida

• A consulta

Query q = session.createQuery("FROM Cliente c");

List<Cliente> lista = q.list();

• Retornará todas as instâncias de Cliente, indiferente de qual subclasse específica será a instância

Page 39: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

QBC – Query By Criteria

• Construção de consultas a partir de objetos de critério

• Permite que se especifique dinamicamente (em tempo de execução) as restrições da consulta

• Sem manipulação (perigosa) de Strings Diretamente

• Um pouco menos legível que HQL

Page 40: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Exemplo QBC

Criteria criteria = session.createCriteria(Cliente.class);

Criteria.add(Expression.like(“nome”,Luiz”));

List result = criteria.list();

Page 41: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Exemplo QBC

Cliente exemplo = new Cliente();

Exemplo.setNome(“Luiz”);

Criteria criteria = session.createCriteria(Cliente.class);

Criteria.add(Example.create(exemplo));

List result = criteria.list();

Page 42: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Transações• Conjunto de ações que devem:

– executarem todas com sucesso;– falhar todas coletivamente;

• Uma transação deve se comportar como uma unidade atômica

• Exemplo: transação bancaria transferir

• Transações podem existir em um aplicação de apenas um usuário

• Mas é mais comum usar-se transações em ambientes concorrentes

• Para indicar que uma transação é bem sucedida, chamamos commit

• Para indicar que uma transação deve ser desfeita (provavelmente pela falha de uma das ações da transação), chamamos rollback

Page 43: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Propriedades ACID

Transações devem possuir as propriedades seguintes, que são conhecidas pelo acrônimo ACID:

• A – Atomicidade• C – Consistência• I – Isolamento• D - Durabilidade

//Pseudo-código

try{

beginTransaction();

executeActions();

commit();

}catch(Exception e){

rollback();

}

Page 44: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Exercício

• Refatorar os DAO´s para as entidades Cliente e Telefone, escritos anteriormente utilizando Hand-coding JDBC, desta vez utilizando a tecnologia Hibernate

• Não altere as interfaces dos DAO´s

• Mantenham as mesmas funcionalidades

Page 45: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP Java Avançado Hibernate II.

Luiz Carlos d´Oleron – [email protected]

Bibliografia

• HIbernate in Action, Bauer & King, Ed. Manning

• On-line hibernate documentation, http://www.hibernate.org/5.html

• Diversos artigos em http://www.theserverside.com

• Apresentações PEC-Hibernate, Jobson Ronan