In Spring-based applications, database access using JPA can be done in two primary ways:
- JpaRepository (Spring Data JPA abstraction)
- EntityManager (core JPA API)
Both are used to perform CRUD operations, but they differ significantly in level of abstraction, control, and use cases.
Understanding when to use which is critical for real-world backend systems and is a frequent interview topic.
JpaRepository is a Spring Data JPA interface that provides ready-made CRUD and pagination operations without writing boilerplate code.
It extends:
CrudRepository → PagingAndSortingRepository → JpaRepository
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}No implementation is required — Spring generates it at runtime.
EntityManager is the core JPA interface responsible for managing:
- entity lifecycle
- persistence context
- database operations
It provides low-level control over persistence operations.
@PersistenceContext
private EntityManager entityManager;| Aspect | JpaRepository | EntityManager |
|---|---|---|
| Abstraction | High | Low |
| Boilerplate code | Minimal | High |
| Control | Limited | Full |
| Learning curve | Easy | Steep |
| Typical usage | Standard CRUD | Complex queries / fine-grained control |
userRepository.save(user);
userRepository.findById(id);
userRepository.delete(user);entityManager.persist(user);
entityManager.find(User.class, id);
entityManager.remove(user);JpaRepository is cleaner and faster to write.
List<User> findByStatusAndRole(String status, String role);@Query("SELECT u FROM User u WHERE u.email = :email")
User findByEmail(@Param("email") String email);TypedQuery<User> query =
entityManager.createQuery(
"SELECT u FROM User u WHERE u.email = :email",
User.class
);
query.setParameter("email", email);
return query.getSingleResult();More verbose, but more flexible.
- Automatically manages persistence context
- Transactions handled via
@Transactional - Simplifies entity state management
-
Direct interaction with persistence context
-
Explicit control over:
- flush
- clear
- detach
- merge
Example:
entityManager.flush();
entityManager.clear();Useful in batch processing and performance tuning.
@Transactional
public void saveUser(User user) {
userRepository.save(user);
}Spring manages everything.
@Transactional
public void updateUser(User user) {
entityManager.merge(user);
}Still needs Spring transactions, but behavior is more explicit.
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}Used when:
- CRUD heavy applications
- REST APIs
- Standard business logic
Batch processing example:
@Transactional
public void bulkInsert(List<User> users) {
for (int i = 0; i < users.size(); i++) {
entityManager.persist(users.get(i));
if (i % 50 == 0) {
entityManager.flush();
entityManager.clear();
}
}
}JpaRepository is not suitable here due to memory overhead.
| Aspect | JpaRepository | EntityManager |
|---|---|---|
| Batch operations | Limited | Excellent |
| Native SQL | Supported | Fully supported |
| Fine-grained flushing | No | Yes |
| Caching control | Abstracted | Explicit |
Use JpaRepository when:
- Application is CRUD-heavy
- Business logic is straightforward
- Rapid development is needed
- Team prefers convention over configuration
Used in:
- REST APIs
- Admin dashboards
- CRUD microservices
Use EntityManager when:
- Complex joins or dynamic queries required
- Batch inserts/updates needed
- Performance tuning required
- Need full JPA lifecycle control
- Legacy or complex database schemas
Used in:
- Reporting systems
- ETL pipelines
- High-volume data processing
Yes — very common in real projects.
@Repository
public class CustomUserRepository {
@PersistenceContext
private EntityManager entityManager;
}Spring Data allows custom repository implementations that mix both.
Neither. It depends on the use case.
Yes — Spring Data JPA uses EntityManager under the hood.
No — advanced cases still require EntityManager.
EntityManager, when tuned properly.
No — it is part of Spring Data JPA.
-
JpaRepository is a high-level abstraction
-
EntityManager is low-level and powerful
-
JpaRepository = productivity
-
EntityManager = control
-
Most real projects use both
-
Choose based on complexity, performance, and control needs