DEV Community

Uiratan Cavalcante
Uiratan Cavalcante

Posted on

Como injetar EntityManager com Spring: @PersistenceContext x Construtor

A diferença entre usar @PersistenceContext e injetar EntityManager via construtor depende principalmente do mecanismo de injeção de dependência do Spring e da forma como o EntityManager é gerenciado.


1️⃣ Usando @PersistenceContext

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;

@Repository
public class MeuRepositorio {

    @PersistenceContext
    private EntityManager entityManager;

    public void salvar(Entidade entidade) {
        entityManager.persist(entidade);
    }
}
Enter fullscreen mode Exit fullscreen mode

🔹 Como funciona?

  • @PersistenceContext é a anotação padrão do JPA para injeção do EntityManager.
  • O Spring detecta essa anotação e injeta um EntityManager gerenciado pelo contexto de persistência.
  • Normalmente, esse EntityManager é transacional e atrelado à transação do Spring.

Vantagens

✔️ Garante que o EntityManager é gerenciado corretamente pelo Spring.

✔️ Facilita a integração com o JPA sem necessidade de configuração adicional.

✔️ Garante que a instância do EntityManager pertence ao escopo correto da transação.

Desvantagens

❌ Não permite injeção via construtor (dificulta testes unitários sem Spring).

❌ Não pode ser usado em atributos final (impede imutabilidade).


2️⃣ Injetando EntityManager via Construtor

import javax.persistence.EntityManager;
import org.springframework.stereotype.Repository;

@Repository
public class MeuRepositorio {

    private final EntityManager entityManager;

    public MeuRepositorio(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public void salvar(Entidade entidade) {
        entityManager.persist(entidade);
    }
}
Enter fullscreen mode Exit fullscreen mode

🔹 Como funciona?

  • O Spring injeta o EntityManager diretamente no construtor da classe.
  • Funciona porque o Spring Boot gerencia o EntityManagerFactory e fornece um EntityManager apropriado como dependência.

Vantagens

✔️ Permite injeção via construtor, facilitando testes unitários sem Spring.

✔️ Torna os campos final, favorecendo imutabilidade e injeção de dependências explícita.

✔️ Reduz o acoplamento com a API do JPA (@PersistenceContext não é necessário).

Desvantagens

❌ Depende da configuração automática do Spring para fornecer um EntityManager.

❌ Se usado fora do contexto correto, pode resultar em TransactionRequiredException.


🔥 Qual Opção Escolher?

Critério @PersistenceContext Injeção via Construtor
Gerenciamento do Spring Sim (injeção automática) Sim (injeção automática)
Escopo da Transação Automático Depende do contexto do Spring
Facilidade de Teste Mais difícil (precisa de @Mock ou Spring) Mais fácil (injeção direta)
Imutabilidade Não suporta final Suporta final
Padrão Recomendado Antigo, mas ainda funcional Recomendado para Clean Architecture

Se você está seguindo boas práticas modernas (Clean Architecture, DDD, SOLID, imutabilidade), use injeção via construtor.

Se você precisa de compatibilidade com um código legado ou quer um EntityManager sempre atrelado ao contexto de persistência do JPA, @PersistenceContext é uma escolha válida.

Top comments (0)