O documento discute vários tópicos relacionados ao Hibernate e JPA, incluindo: 1) Uma breve introdução ao Hibernate como framework para mapeamento objeto-relacional; 2) A diferença entre JPA e Hibernate, onde JPA é uma especificação e Hibernate uma implementação; 3) Algumas exceções comuns como LazyInitializationException e como resolvê-las.
4. Antes que eu me esqueça...
Fica, vai ter brindes.
5. 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.
6. 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”.
7. LOL! Agora posso esquecer do
banco de dados e pensar só nos
objetos!
What??? Wait!!
8. Não esqueça do Banco de Dados
Pelo 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!
9. 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 {
12. LazyInitializationException
Session 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.
13. TransientObjectException
Autor 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.
15. PersistentObjectException
Produto 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.
16. 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
17. 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.
18. Cuidado com as n+1 queries
Uma 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.
19. 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.
20. 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.
21. 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
22. Utilize o Hibernate Statistics
Saiba 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.
23. Uuuuuii! Ele não usa SQL...
assim pode mudar de banco de dados a
hora que quiser.
24. 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.
25. 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.