Ao criar relacionamentos entre entidades com JPA, como um Pedido
com seus Itens
,
precisamos decidir quando carregar
esses dados relacionados. A escolha entre as estratégias Lazy (preguiçosa) e Eager
(apressada) afeta diretamente a
performance da sua aplicação. Vamos entender isso de forma rápida.
Explicação
Pense em uma série de um serviço de streaming:
- Eager (Apressado): É como baixar a temporada inteira de uma vez antes de assistir ao primeiro episódio. Você tem tudo na mão, mas gasta mais tempo e dados inicialmente.
- Lazy (Preguiçoso): É como assistir episódio por episódio (streaming). Você carrega apenas o que vai ver agora, economizando recursos.
No JPA:
- FetchType.EAGER: Carrega a entidade principal e imediatamente busca todas as suas entidades relacionadas em uma única consulta.
- FetchType.LAZY: Carrega apenas a entidade principal. Os dados relacionados só são buscados do banco se você explicitamente tentar usá-los no código.
Por padrão, relacionamentos como @OneToMany
(um-para-muitos) são Lazy, enquanto @ManyToOne
(muitos-para-um) é Eager.
Exemplo Prático
Vamos imaginar uma Categoria
com vários Produtos
.
@Entity
public class Categoria {
@Id
private Long id;
private String nome;
// A estratégia de busca é definida aqui
@OneToMany(mappedBy = "categoria", fetch = FetchType.LAZY)
private List<Produto> produtos;
// ...
}
Como o JPA reage:
- Com
FetchType.LAZY
:- Código:
repository.findById(1L);
- SQL:
SELECT * FROM Categoria WHERE id = 1;
- Resultado: Apenas a categoria é carregada. A lista de produtos só será buscada do banco
se você chamar o método
getProdutos()
.
- Código:
- Com
FetchType.EAGER
:- Código:
repository.findById(1L);
- SQL:
SELECT * FROM Categoria c LEFT JOIN Produto p ON c.id = p.categoria_id WHERE c.id = 1;
- Resultado: A categoria e todos os seus produtos são carregados do banco de uma só vez.
- Código:
Conclusão
A regra geral é simples: prefira Lazy
. Ele evita carregar dados desnecessários e previne problemas de
performance,
principalmente em listas longas. Use EAGER
apenas quando tiver certeza absoluta de que sempre precisará
dos dados
relacionados junto com a entidade principal.
Essa pequena escolha tem um grande impacto. Dominá-la é um passo importante para criar aplicações Java eficientes e escaláveis.