java-jpa-hibernate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Java JPA Hibernate Skill

Java JPA Hibernate 技能指南

Master data persistence with JPA and Hibernate for production applications.
掌握使用JPA和Hibernate实现生产级应用的数据持久化。

Overview

概述

This skill covers JPA entity design, Hibernate optimization, Spring Data repositories, query strategies, and caching. Focuses on preventing N+1 queries and building high-performance persistence layers.
本技能涵盖JPA实体设计、Hibernate优化、Spring Data仓库、查询策略及缓存。重点讲解如何避免N+1查询并构建高性能持久化层。

When to Use This Skill

适用场景

Use when you need to:
  • Design JPA entities with relationships
  • Optimize database queries
  • Configure Hibernate for performance
  • Implement caching strategies
  • Debug persistence issues
当你需要以下操作时使用本技能:
  • 设计带关联关系的JPA实体
  • 优化数据库查询
  • 配置Hibernate以提升性能
  • 实现缓存策略
  • 调试持久化相关问题

Topics Covered

涵盖主题

Entity Design

实体设计

  • Entity mapping annotations
  • Relationship types (1:1, 1:N, N:M)
  • Inheritance strategies
  • Lifecycle callbacks
  • Auditing
  • 实体映射注解
  • 关联关系类型(一对一、一对多、多对多)
  • 继承策略
  • 生命周期回调
  • 审计功能

Query Optimization

查询优化

  • N+1 problem prevention
  • JOIN FETCH vs EntityGraph
  • Batch fetching
  • Projections and DTOs
  • N+1问题的预防
  • JOIN FETCH 与 EntityGraph对比
  • 批量抓取
  • 投影与DTO

Transactions

事务

  • @Transactional configuration
  • Propagation and isolation
  • Optimistic vs pessimistic locking
  • Deadlock prevention
  • @Transactional配置
  • 传播性与隔离级别
  • 乐观锁 vs 悲观锁
  • 死锁预防

Caching

缓存

  • First and second level cache
  • Query cache
  • Cache invalidation
  • Redis integration
  • 一级缓存与二级缓存
  • 查询缓存
  • 缓存失效
  • Redis集成

Quick Reference

快速参考

java
// Entity with relationships
@Entity
@Table(name = "orders")
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "customer_id", nullable = false)
    private Customer customer;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
    @BatchSize(size = 20)
    private List<OrderItem> items = new ArrayList<>();

    @Version
    private Long version;

    // Bidirectional helper
    public void addItem(OrderItem item) {
        items.add(item);
        item.setOrder(this);
    }
}

// Auditing base class
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class Auditable {
    @CreatedDate
    @Column(updatable = false)
    private Instant createdAt;

    @LastModifiedDate
    private Instant updatedAt;
}

// Repository with query optimization
public interface OrderRepository extends JpaRepository<Order, Long> {

    // JOIN FETCH to prevent N+1
    @Query("SELECT DISTINCT o FROM Order o JOIN FETCH o.items WHERE o.status = :status")
    List<Order> findByStatusWithItems(@Param("status") Status status);

    // EntityGraph alternative
    @EntityGraph(attributePaths = {"items", "customer"})
    Optional<Order> findById(Long id);

    // DTO Projection
    @Query("SELECT new com.example.OrderSummary(o.id, o.status, c.name) " +
           "FROM Order o JOIN o.customer c WHERE o.id = :id")
    Optional<OrderSummary> findSummaryById(@Param("id") Long id);
}
java
// 带关联关系的实体
@Entity
@Table(name = "orders")
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "customer_id", nullable = false)
    private Customer customer;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
    @BatchSize(size = 20)
    private List<OrderItem> items = new ArrayList<>();

    @Version
    private Long version;

    // 双向关联辅助方法
    public void addItem(OrderItem item) {
        items.add(item);
        item.setOrder(this);
    }
}

// 审计基类
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class Auditable {
    @CreatedDate
    @Column(updatable = false)
    private Instant createdAt;

    @LastModifiedDate
    private Instant updatedAt;
}

// 带查询优化的仓库
public interface OrderRepository extends JpaRepository<Order, Long> {

    // 使用JOIN FETCH避免N+1查询
    @Query("SELECT DISTINCT o FROM Order o JOIN FETCH o.items WHERE o.status = :status")
    List<Order> findByStatusWithItems(@Param("status") Status status);

    // EntityGraph替代方案
    @EntityGraph(attributePaths = {"items", "customer"})
    Optional<Order> findById(Long id);

    // DTO投影
    @Query("SELECT new com.example.OrderSummary(o.id, o.status, c.name) " +
           "FROM Order o JOIN o.customer c WHERE o.id = :id")
    Optional<OrderSummary> findSummaryById(@Param("id") Long id);
}

N+1 Prevention Strategies

N+1查询预防策略

StrategyUse WhenExample
JOIN FETCHAlways need relation
JOIN FETCH o.items
EntityGraphDynamic fetching
@EntityGraph(attributePaths)
@BatchSizeCollection access
@BatchSize(size = 20)
DTO ProjectionRead-only queries
new OrderSummary(...)
策略适用场景示例
JOIN FETCH始终需要关联数据
JOIN FETCH o.items
EntityGraph动态抓取数据
@EntityGraph(attributePaths)
@BatchSize访问集合数据
@BatchSize(size = 20)
DTO投影只读查询
new OrderSummary(...)

Hibernate Configuration

Hibernate配置

yaml
spring:
  jpa:
    open-in-view: false  # Critical!
    properties:
      hibernate:
        jdbc.batch_size: 50
        order_inserts: true
        order_updates: true
        default_batch_fetch_size: 20
        generate_statistics: ${HIBERNATE_STATS:false}

  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      leak-detection-threshold: 60000
yaml
spring:
  jpa:
    open-in-view: false  # 至关重要!
    properties:
      hibernate:
        jdbc.batch_size: 50
        order_inserts: true
        order_updates: true
        default_batch_fetch_size: 20
        generate_statistics: ${HIBERNATE_STATS:false}

  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      leak-detection-threshold: 60000

Troubleshooting

故障排查

Common Issues

常见问题

ProblemCauseSolution
N+1 queriesLazy in loopJOIN FETCH, EntityGraph
LazyInitExceptionSession closedDTO projection
Slow queriesMissing indexEXPLAIN ANALYZE
Connection leakNo @TransactionalAdd annotation
问题原因解决方案
N+1查询循环中使用懒加载使用JOIN FETCH、EntityGraph
LazyInitException会话已关闭使用DTO投影
查询缓慢缺少索引执行EXPLAIN ANALYZE
连接泄漏未添加@Transactional添加注解

Debug Properties

调试属性

properties
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.orm.jdbc.bind=TRACE
hibernate.generate_statistics=true
properties
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.orm.jdbc.bind=TRACE
hibernate.generate_statistics=true

Debug Checklist

调试检查清单

□ Enable SQL logging
□ Check query count per request
□ Verify fetch strategies
□ Review @Transactional
□ Check connection pool
□ 启用SQL日志
□ 检查每个请求的查询次数
□ 验证抓取策略
□ 检查@Transactional配置
□ 检查连接池

Usage

使用方式

Skill("java-jpa-hibernate")
Skill("java-jpa-hibernate")

Related Skills

相关技能

  • java-performance
    - Query optimization
  • java-spring-boot
    - Spring Data
  • java-performance
    - 查询优化
  • java-spring-boot
    - Spring Data