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)