Spring Data JPA Patterns
Spring Data JPA and Hibernate patterns for efficient data access. Optimize queries before optimizing code.
Selective Reading Rule
Read only files relevant to the request. Use the content map to focus.
Content Map
| File | Description | When to Read |
|---|---|---|
entities.md | Entity design, relationships | Modeling |
repositories.md | Derived queries, custom JPQL | Repository layer |
optimization.md | N+1, batch fetching, projections | Performance |
transactions.md | @Transactional and isolation | Transaction management |
Core Patterns
1. Entity Design
java
@Entity
@Table(name = "users", indexes = {
@Index(name = "idx_users_email", columnList = "email", unique = true)
})
public class User {
@Id
private String id;
@Column(nullable = false, unique = true)
private String email;
@Enumerated(EnumType.STRING)
private UserStatus status;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserRole> roles = new ArrayList<>();
}
2. Repository Queries
java
public interface UserRepository extends JpaRepository<User, String> {
Optional<User> findByEmail(String email);
@Query("""
SELECT u FROM User u
LEFT JOIN FETCH u.roles r
WHERE u.status = :status
""")
List<User> findByStatusWithRoles(@Param("status") UserStatus status);
}
3. Avoid N+1
java
@EntityGraph(attributePaths = {"roles", "roles.role"})
List<User> findByStatus(UserStatus status);
// Or use batch fetch size
// spring.jpa.properties.hibernate.default_batch_fetch_size=100
4. Transactions
java
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
@Transactional(readOnly = true)
public Optional<User> findById(String id) {
return userRepository.findById(id);
}
@Transactional
public User create(User user) {
return userRepository.save(user);
}
}
Decision Checklist
- •Entities reflect aggregate boundaries?
- •Lazy loading by default?
- •Fetch joins or projections for read endpoints?
- •Transactions applied at service layer?
Anti-Patterns
| Anti-Pattern | Why Bad | Better Approach |
|---|---|---|
| EAGER by default | Performance issues | Lazy + explicit fetch |
| Entity as DTO | Overfetching | Projection/DTO |
| @Transactional on class | Leaky scope | Per-method |
Related Skills
| Need | Skill |
|---|---|
| Core Spring patterns | @[skills/spring-boot-patterns] |
| Testing | @[skills/spring-testing] |