Java Enterprise Edition - JEE
05. Relacionamento bidirecional e Lazyness
Esp. Márcio Palheta
Relacionamento bidirecional
Para acessar os dados da Conta de uma Movimentação, utilizamos a anotação
@ManyToOne;
@ManyToOne;
Agora, nosso objetivo é acessar as
Movimentações a partir de uma Conta;
Para isso, precisaremos criar um
atributo em Conta para guardar a
Exercício 01
Inclua uma coleção para guardar as
Movimentações da Conta:
Itens a ponderar
A inclusão do novo mapeamento não deveria mudar nada na estrutura das tabelas;
tabelas;
A tabela movimentacao já tem a chave estrangeira para a tabela de contas;
Para verificar se está tudo correto, rode
novamente a classe TestePersistencia;
Surgimento de nova tabela
Após a execução da classe de teste,
acesse o banco de dados para verificar se há algo diferente;
se há algo diferente;
Foi criada a tabela Conta_Movimentacao
A nova tabela possui os campos:
Int conta_id;
Int movimentacoes_id;
Relacional vs Objetos
No banco de dados, a chave estrangeira já representa:
A relação muitos-para-um da movimentação
A relação muitos-para-um da movimentação para a conta; e
A relação um-para-muitos da conta para as movimentações;
Mas no mundo OO, essa relação não é
Mapeamento bidirecional
Não é porque temos um atributo Conta na classe Movimentação, que teremos, automaticamente um atributo
automaticamente um atributo
List<Movimentacao> na classe Conta;
Tivemos que fazer isso manualmente;
O inverso também não é obrigatório;
Mapeamento bidirecional
Para a JPA, existem duas relações distintas;
Por isso o Hibernate criou a tabela
Conta_Movimentacao para representar o Conta_Movimentacao para representar o mapemento um-para-muitos;
Precisamos que o Hibernate entenda que OneToMany representa o mesmo
relacionamento mapeado em ManyToOne
Mapeamento Bidirecional
A anotação OneToMany tem um atributo mappedBy;
mappedBy indica que a relação é a
mappedBy indica que a relação é a mesma representada pelo atributo conta da classe Movimentacao;
A seguir, vamos atualizar a anotação
@OneToMany da classe Conta
Exercício 02
Atualize a classe Conta e exclua a
tabela Conta_Movimentacao do BD:
Exercício 03
Crie a classe TesteBiderecional;
No método main(), crie objetos ContaDAO e MovimentacaoDAO;
ContaDAO e MovimentacaoDAO;
Pesquise uma conta e imprima sua movimentações;
Pesquise uma movimentação e imprima
os dados de sua conta;
Itens a ponderar
A classe sem mappedBy determina o modelo de banco de dados;
Essa classe é chamada de owning entity
Essa classe é chamada de owning entity ou lado forte da relação;
A classe com mappedBy é conhecida
como inverse entity ou lado fraco da
relação;
Mapeamento ManyToMany
Nossos usuários viram a necessidade de classificar melhor as movimentações,
alem de ENTRADA ou SAIDA;
alem de ENTRADA ou SAIDA;
Vamos permitir que o usuário associe TAGs às suas movimentações;
A seguir, verificaremos as mudanças
necessárias ao modelo;
Atualização do modelo
Exercício 04
Atualização da Movimentação
Na classe Movimentacao, incluiremos um atributo List<Tag> tags para
guardar a coleção de Tags;
guardar a coleção de Tags;
O novo atributo será marcado com
@ManyToMany;
O Hibernate criará uma tabela de
relacionamento para representar N x N
Exercício 05
Criando a classe TagDAO
Vamos criar uma classe TagDAO para persistir as tags da nossa aplicação;
Criaremos um método para cadastrar
Criaremos um método para cadastrar ou consultar uma tag, com base no nome;
O método main() testa a persistência;
Qual o resultado da execução?
Exercício 06 - TagDAO
Exercício 07 - TesteTagDAO
NoResultException
Exceção lançada quando não há
resultado para query.getSingleResult();
Exercício 08 – Try ... Catch
Exercício 09
Exercício 09 – continuação
Exercício 10
Estados de entidades
Managed(gerenciado) – o Hibernate garante que o objeto terá
representação idêntica ao do banco;
representação idêntica ao do banco;
Transient – objetos que não possuem representação no banco(new);
Usamos em.persist() para passar de
Transient para Managed;
Estados de entidades
Detached – um objeto é managed enquanto o entityManager estiver aberto.
aberto.
Com em.close(), o objeto passa de managed para detached;
Removed – logo após executar
em.remove(), o objeto deixa de existir
no banco, mas continua em
LazyInitializationException
Listar Movimentações e Tags
EntityManager e Transação gerenciados pela camada de controle;
pela camada de controle;
A tela imprime a movimentação, mas quando tenta imprimir as Tags...
Ocorre exceção porque o EM já está
fechado;
Decisões sobre as consultas
Lazy load – carregamento lento. A
carga da coleção não ocorre junto com a carga do objeto que a contem;
Eager – a coleção é carregada junto
Eager – a coleção é carregada junto
com o objeto que a contem;
Hibernate e pool de conexões
Acesso simultâneo de muitos usuários;
Criar conexão é um processo custoso;
Podemos gerenciar as conexões
Podemos gerenciar as conexões gerando um Pool de Conexões;
O Hibernate tem um pool embutido
c3p0
Exercício 11
Copie e adicione as libs do c3p0 ao classpath da aplicação.
Atualize o persistence.xml
Atualize o persistence.xml
Outros mapeamentos
Em nosso modelo, toda Conta deve possuir um Gerente;
E o Gerente só pode ser responsável
E o Gerente só pode ser responsável por uma Conta;
Anotação @OneToOne
A seguir, mostramos a criamos a nova
classe Gerente:
Exercício 12
Exercício 13
O pattern Value Object
Objetos que servem para representar
um ou mais valores relativos ao domínio
Objetos que não precisam ser
Objetos que não precisam ser identificáveis
Em nosso modelo, poderíamos
reaproveitar a estrutura de Endereço do
Gerente, para outras classes;
Value Object e Embeddable
O gerente tem endereço com: rua, cidade e estado;
Outras entidades podem precisar dessa
Outras entidades podem precisar dessa informação;
Vamos isolar o código de endereço em uma nova classe;
NÃO vamos gerar uma nova tabela
A classe Endereco
A classe endereço terá os atributos:
rua, cidade e estado;
Mas essa nova classe não deve ser uma
Mas essa nova classe não deve ser uma entidade;
Um objeto Endereço pode ser embutido
em outros objetos
Exercício 14
Classe Endereco marcada com
@Embeddable
Exercício 15
Atualização da classe Gerente
Exercício 16
Criar uma classe de teste
Cadastrar gerentes;
Associar gerentes a contas;
Associar gerentes a contas;
Listar conta / gerente;
Consultar conta por gerente;
Chaves compostas
A representação de chaves compostas no Hibernate se dá pela criação de uma nova classe, para representar a chave
nova classe, para representar a chave de uma entidade;
A nova classe devem implementar a interface Serializable;
Classe anotada com @Embeddable
Representacao - ID do cliente
Classe entidade Cliente
Referências
www.caelum.com.br
http://hibernate.org/docs
Hall, Marty, “Core Servlets and Java Server
Hall, Marty, “Core Servlets and Java Server Pages”, Janeiro 2002, Sun Microsystems
Press;