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);
}
}
🔹 Como funciona?
-
@PersistenceContexté a anotação padrão do JPA para injeção doEntityManager. - O Spring detecta essa anotação e injeta um
EntityManagergerenciado 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);
}
}
🔹 Como funciona?
- O Spring injeta o
EntityManagerdiretamente no construtor da classe. - Funciona porque o Spring Boot gerencia o
EntityManagerFactorye fornece umEntityManagerapropriado 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)