Upload
frederico-maia-arantes
View
4.247
Download
2
Embed Size (px)
DESCRIPTION
Palestra sobre o tema "Boas Práticas com JPA 2 e Hibernate". Apresentada no FLISOL 2012 em Goiânia (GO). Não poderia deixar de citar como fonte o excelente blog da Caleum. http://blog.caelum.com.br/
Citation preview
Frederico Maia Arantes
Boas Práticas
JPA 2 e Hibernate
Sobre mimFrederico Maia Arantes / @fredmaia
Programador Java EE na PC SistemasOracle Certified Java SE 6 Programmer (OCJP 6)Instrutor Java na Supera TecnologiaJUGLeader do GojavaArtigo na Easy Java Magazine (Devmedia)http://devsexperts.com
Sobre vocês?
Antes que eu me esqueça...
Fica, vai ter brindes.
O Hibernate
Framework para mapeamento Objeto Relacional.
Mapear o banco para as classes.
Simplifica o desenvolvimento e aumenta
produtividade. Independência de banco de dados e
muitas outras vantagens.
Mas é preciso conhecer bem seus frameworks.
Qual a diferença entre JPA e Hibernate?
JPA é uma especificação.
Hibernate é uma implementação.
Hibernate surgiu primeiro e a JPA foi inspirada em
frameworks como ele, TopLink, EclipseLink.
JPA são “regras” de como deve ser feito. O Hibernate
pode ser usado como implementação destas regras
ou com suas “próprias regras”.
LOL! Agora posso esquecer do banco de dados e pensar só nos objetos!
What??? Wait!!
Não esqueça do Banco de DadosPelo contrário, tenha muita atenção para não perder
performance!
Em OO pensamos em especializar, dividir
responsabilidades, classes pequenas e coesas.
No banco de dados nem sempre é bom dividir, as vezes é
bom unir e evitar consultas com vários joins desnecessários.
Em banco de dados não existe herança!
Entenda as estratégias herança
Você deve entender as estratégias de herança do
JPA e Hibernate:@SingleTable
@Joined
@TablePerClass
public class Pessoa extends PessoaJuridica {
E essas aqui, conhece?
LazyInitializationException
TransientObjectException
PersistentObjectException
LazyInitializationExceptionSession session = sessionFactory.openSession();NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal.class, 42);session.close();List<Item> items = nf.getItems();System.out.println("numero de pedidos:" + items.size());
org.hibernate.LazyInitializationException
Porque? Como resolver?
Sessão fechada ao tentar buscar os itens.
Eager, manter a sessão aberta ou fetch.
O ideal? Planeje suas queries, use Lazy nos relacionamentos e
fetch ao buscar os registros.
TransientObjectExceptionAutor a = new Autor();Livro l = new Livro();a.setLivros(Collections.singleton(l));manager.persist(a);
org.hibernate.TransientObjectException - object references an unsaved transient
instance
Porque? Como resolver?
Livro não está sendo salvo, apenas o autor.
Chame o persist(l) na transação ou use Cascade no
relacionamento entre Autor e Livro.
Ministério do JPA adverte:
Use Cascade com moderação.
PersistentObjectExceptionProduto p = new Produto();
p.setId(1l);
p.setDescricao(“Computador”);
manager.persist(p);
org.hibernate.PersistentObjectException: detached entity passed to persist
Porque? Como resolver?
Seu id está @GeneratedValue e sua entidade detached.
Deveria estar transiente ou managed.
Antes de persistir use o find, ou o merge.
Entenda os estados das entidades JPA
Transient ou New: não possui identidade e não
está associado a um EntityManager
Managed: possui identidade, está associado, seu
conteúdo é sincronizado com o banco de dados
Detached: possui identidade, mas não está
associado, portanto não é sincronizado
Cuidado com o Lazy
Cuidado com OpenSessionInView para resolver
Lazy exceptions.
Planeje suas queries.
Monte-as para obter o resultado de acordo com o
que precisa em cada cenário.
Cuidado com as n+1 queriesUma NotaFiscal com Items lazy, gastamos
duas queries. Para uma lista de NotaFiscal
resultante de uma query, para cada
NotaFiscal teremos uma nova query executada para
todo getItems invocados. 1 query para
listar NotaFiscal, N queries para pegar os relacionamentos.
Use configurações de batch-size e fetch-size para carregar as
entidades/relacionamentos em blocos em vez de 1 em 1.
Utilize second level cache
Utilize second level cache para consultas que você
precisa muito.
Estes dados não devem ser alterados com
frequência.
Reduza suas idas ao banco de dados.
Utilize um pool de conexões
Mantém um número (que você define) de conexões
abertas sempre, evita o custo de abrí-las a todo o
momento e cair no OneSessionPerRequest.
Se estiver usando o hibernate sem um servidor EE
uma boa opção é o C3P0.
Ou utilize um servidor JEE e configue nele mesmo.
Pra que buscar sempre o objeto inteiro?
Você tem na tela uma combobox de fornecedores
e precisa de Id e Nome.
Vai usar um “from Fornecedor” e trazer Id, Nome,
CNPJ, Razão Sozial, CNAE, Endereço, Status,
Tipo do Fornecedor... ?
Use: select f.id, f.nome from Fornecedor f
Utilize o Hibernate StatisticsSaiba quantas vezes cada entidade, coleção
(relacionamento) e query está sendo
carregada/executada.
Quantas vezes o cache foi usado.
Tempo médio de cada query.
Com estes dados, saiba onde colocar cache,
configurar batchsize e fazer joins com fetch eager.
Uuuuuii! Ele não usa SQL...
assim pode mudar de banco de dados a hora que quiser.
Vai mesmo mudar de banco de dados?
Poucos sistemas tem que rodar realmente em vários
BD’s ou têm possibilidade de serem alterados.
Seu sistema se encaixa neste cenário?
Então não tenho medo de utilizar SQL nativo se
precisar. Você pode estar perdendo excelentes
recursos que os bancos de dados oferecem.
Estude a documentação
Estude a especificação do JPA.
Estude a documentação do Hibenate.
Estude o capítulo de performance do hibernate.
Estude seu banco de dados.
Estude... sempre.