AgentSkillsCN

spring-data-jpa

Spring Data JPA 与 Hibernate 在实体、仓储及查询性能方面的最佳实践

SKILL.md
--- frontmatter
name: spring-data-jpa
description: Spring Data JPA and Hibernate patterns for entities, repositories, and query performance
keywords:
  - spring-data-jpa
  - jpa
  - hibernate
  - entity
  - repository
  - query
  - jpql
  - criteria
  - lazy loading
  - fetch join
  - transaction
filePatterns:
  - "*.java"
  - "application.yml"
  - "application.properties"
frameworks:
  - spring-data-jpa
  - jpa
  - hibernate
tokenCount: 3200
version: 1.0.0

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

FileDescriptionWhen to Read
entities.mdEntity design, relationshipsModeling
repositories.mdDerived queries, custom JPQLRepository layer
optimization.mdN+1, batch fetching, projectionsPerformance
transactions.md@Transactional and isolationTransaction 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-PatternWhy BadBetter Approach
EAGER by defaultPerformance issuesLazy + explicit fetch
Entity as DTOOverfetchingProjection/DTO
@Transactional on classLeaky scopePer-method

Related Skills

NeedSkill
Core Spring patterns@[skills/spring-boot-patterns]
Testing@[skills/spring-testing]