How to access entity manager with spring boot and spring data
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Spring Data JPA lets you stay productive through repository interfaces, derived queries, and paging support. Even so, some cases still need direct access to EntityManager, especially when you need custom JPQL, batch updates, Criteria API queries, or explicit control over flushing and persistence context behavior.
Core Sections
The normal way to obtain EntityManager
In a Spring Boot application, you usually inject EntityManager into a Spring-managed bean with @PersistenceContext. That keeps the persistence context tied to the current transaction and lets Spring handle setup for you.
This is the idiomatic approach. Avoid constructing EntityManager yourself in application code. In a Spring app, manual creation almost always means you are stepping outside the transaction model that the framework is already maintaining.
Why repositories are not always enough
A plain JpaRepository handles most CRUD work well, but direct EntityManager access becomes useful when the query logic is too dynamic or too specialized for a derived method name. Typical examples include:
- dynamic filtering with Criteria API
- optimized fetch joins to avoid repeated lazy loading
- bulk update or delete queries
- explicit
flushorclearcalls during batch processing - native queries for database-specific features
Spring Data removes boilerplate, but it does not replace JPA itself. When repository methods become awkward, moving the advanced part into a custom component keeps the codebase clearer.
Using a custom repository implementation
The common pattern is to extend the Spring Data repository with a custom interface and then implement that custom part with EntityManager.
This keeps the standard repository interface available for normal CRUD while isolating the lower-level JPA work to a place where that complexity is expected.
Transactions decide how the persistence context behaves
Reading with EntityManager may work outside an explicit transaction in some configurations, but any write-oriented logic should be executed inside a transactional boundary. Without that, changes may not be flushed when you expect, and lazy associations may fail later.
Inside a transaction, the managed entity is tracked automatically. You usually do not need to call save after mutating it, because JPA dirty checking will pick up the change before commit.
@PersistenceContext versus constructor injection
You will also see EntityManager injected through a constructor. That can work in Spring because the framework provides a proxy, but @PersistenceContext still communicates intent more clearly in JPA-heavy code.
Either style is acceptable in Spring Boot. The main rule is simpler: inject it only into Spring-managed beans such as @Repository, @Service, or @Component classes.
Common Pitfalls
- Injecting
EntityManagerinto a class created withnewbypasses Spring and leaves the field unset. - Putting advanced JPQL or Criteria code directly inside controllers makes persistence logic harder to test and maintain.
- Running write operations without
@Transactionalcan produce missing updates, lazy-loading failures, or confusing flush behavior. - Using bulk update queries without clearing or refreshing the persistence context can leave managed entities out of sync with the database.
- Replacing all repository methods with direct
EntityManagerusage adds boilerplate without improving the design.
Summary
- Access
EntityManagerin Spring Boot through dependency injection, usually with@PersistenceContext. - Keep normal CRUD in Spring Data repositories and reserve
EntityManagerfor advanced JPA cases. - Custom repository implementations are the cleanest place for manual JPQL or Criteria logic.
- Transaction boundaries matter because they define how the persistence context tracks entities.
- Use direct
EntityManageraccess deliberately, not as a default replacement for repositories.
Related reading
- How to access host port from docker container
- How to access hosts in my network from microk8s deployment pods
- How to access host's localhost from inside kubernetes cluster
- How to access HTTP headers for request to AWS API Gateway using Lambda?
- How to access outer class from an inner class?
- How to access Spring-boot JMX remotely
- How to access mysql outside my kubernetes cluster?
- How to access service created in another namespace

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.