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
<span>import</span> <span>javax.persistence.EntityManager</span><span>;</span><span>import</span> <span>javax.persistence.PersistenceContext</span><span>;</span><span>import</span> <span>org.springframework.stereotype.Repository</span><span>;</span><span>@Repository</span><span>public</span> <span>class</span> <span>MeuRepositorio</span> <span>{</span><span>@PersistenceContext</span><span>private</span> <span>EntityManager</span> <span>entityManager</span><span>;</span><span>public</span> <span>void</span> <span>salvar</span><span>(</span><span>Entidade</span> <span>entidade</span><span>)</span> <span>{</span><span>entityManager</span><span>.</span><span>persist</span><span>(</span><span>entidade</span><span>);</span><span>}</span><span>}</span><span>import</span> <span>javax.persistence.EntityManager</span><span>;</span> <span>import</span> <span>javax.persistence.PersistenceContext</span><span>;</span> <span>import</span> <span>org.springframework.stereotype.Repository</span><span>;</span> <span>@Repository</span> <span>public</span> <span>class</span> <span>MeuRepositorio</span> <span>{</span> <span>@PersistenceContext</span> <span>private</span> <span>EntityManager</span> <span>entityManager</span><span>;</span> <span>public</span> <span>void</span> <span>salvar</span><span>(</span><span>Entidade</span> <span>entidade</span><span>)</span> <span>{</span> <span>entityManager</span><span>.</span><span>persist</span><span>(</span><span>entidade</span><span>);</span> <span>}</span> <span>}</span>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 doEntityManager
. - 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
<span>import</span> <span>javax.persistence.EntityManager</span><span>;</span><span>import</span> <span>org.springframework.stereotype.Repository</span><span>;</span><span>@Repository</span><span>public</span> <span>class</span> <span>MeuRepositorio</span> <span>{</span><span>private</span> <span>final</span> <span>EntityManager</span> <span>entityManager</span><span>;</span><span>public</span> <span>MeuRepositorio</span><span>(</span><span>EntityManager</span> <span>entityManager</span><span>)</span> <span>{</span><span>this</span><span>.</span><span>entityManager</span> <span>=</span> <span>entityManager</span><span>;</span><span>}</span><span>public</span> <span>void</span> <span>salvar</span><span>(</span><span>Entidade</span> <span>entidade</span><span>)</span> <span>{</span><span>entityManager</span><span>.</span><span>persist</span><span>(</span><span>entidade</span><span>);</span><span>}</span><span>}</span><span>import</span> <span>javax.persistence.EntityManager</span><span>;</span> <span>import</span> <span>org.springframework.stereotype.Repository</span><span>;</span> <span>@Repository</span> <span>public</span> <span>class</span> <span>MeuRepositorio</span> <span>{</span> <span>private</span> <span>final</span> <span>EntityManager</span> <span>entityManager</span><span>;</span> <span>public</span> <span>MeuRepositorio</span><span>(</span><span>EntityManager</span> <span>entityManager</span><span>)</span> <span>{</span> <span>this</span><span>.</span><span>entityManager</span> <span>=</span> <span>entityManager</span><span>;</span> <span>}</span> <span>public</span> <span>void</span> <span>salvar</span><span>(</span><span>Entidade</span> <span>entidade</span><span>)</span> <span>{</span> <span>entityManager</span><span>.</span><span>persist</span><span>(</span><span>entidade</span><span>);</span> <span>}</span> <span>}</span>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 umEntityManager
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.
原文链接:Como injetar EntityManager com Spring: @PersistenceContext x Construtor
暂无评论内容