使用 Spring Data JPA 搭配 Hibernate 时,Spring Data JPA 主要负责“上层抽象”,Hibernate 负责“底层实现”,两者通过 JPA 规范 实现协作。下面分层说明它们之间的协作原理:

一、核心角色划分

角色说明
Spring Data JPA提供开发友好的接口(如 JpaRepository),简化数据库操作
JPA(Java Persistence API)定义ORM规范(比如 @Entity, @OneToMany 等)
HibernateJPA 的一个实现,负责底层数据库操作(SQL生成、连接管理等)

二、协作流程分解

以下是一个典型的流程,从你调用接口开始,到 Hibernate 执行 SQL:

1️⃣ 你调用 UserRepository.findByName("Tom")

  • 这是一个接口方法,继承自 JpaRepository
  • Spring Data JPA 会根据方法名自动解析成查询逻辑(叫做方法名解析策略)。

2️⃣ Spring Data JPA 创建查询代理对象

  • 启动时,Spring 使用代理技术(JDK 动态代理 / CGLIB)为你的 UserRepository 生成实现类。
  • 代理类背后调用了 JpaRepository 接口的默认实现(SimpleJpaRepository)

3️⃣ 调用委托给 EntityManager

  • SimpleJpaRepository 调用 JPA 的核心接口 EntityManager 来执行业务逻辑(例如查询、保存等)。

4️⃣ Hibernate 执行 ORM 映射

  • EntityManager 实际由 Hibernate 实现,内部使用 Session。
  • Hibernate 根据实体类的注解信息(如 @Entity@Column 等)构造 SQL。
  • 最终执行 JDBC 操作访问数据库。

三、具体协作链路图(概念图)

你写的代码
   ↓
UserRepository(接口) ← ← ← Spring 自动创建代理对象
   ↓
SimpleJpaRepository(实现类)
   ↓
EntityManager(JPA 接口)
   ↓
Hibernate(JPA 实现)
   ↓
JDBC
   ↓
数据库

四、补充说明

  • JPA 规范是桥梁:Spring Data JPA 和 Hibernate 通过共同遵守 JPA 规范解耦。
  • Hibernate 可以替换:如果你愿意,也可以用 EclipseLink、OpenJPA 等替代 Hibernate,但 Hibernate 是默认实现。
  • Spring Boot 自动配置:自动创建 EntityManagerFactory、数据源等,省去大量配置。

总结

Spring Data JPA 负责接口定义和方法封装,让你专注于业务逻辑;
Hibernate 负责 ORM 细节,依据 JPA 规范进行数据的持久化操作。
两者通过 JPA 接口(EntityManager) 无缝协作,提升开发效率的同时保持灵活性和规范性。

源码调试链路说明

下面是 使用 Spring Data JPA + Hibernate 时的源码调试链路,以调用 userRepository.findByName("Tom") 为例,一步步跟踪背后的源码执行过程:

Spring Data JPA + Hibernate 源码调试链路

场景入口

@Autowired
private UserRepository userRepository;

userRepository.findByName("Tom");

1️⃣ 接口方法被代理(Spring 创建 Repository 代理对象)

Spring 启动时会扫描你定义的 UserRepository,并使用 RepositoryFactoryBeanSupport 创建代理对象:

RepositoryFactoryBeanSupport → getObject() → getRepository()

返回的是一个代理对象,代理逻辑是通过 JpaRepositoryFactory 实现的。

2️⃣ 创建 SimpleJpaRepository 实例作为默认实现类

JpaRepositoryFactory → getTargetRepository()
→ return new SimpleJpaRepository<>(domainClass, entityManager);

你实际调用的 userRepository.findByName() 会委托给 SimpleJpaRepository

3️⃣ 解析方法名:findByName → 自动生成查询

JpaRepositoryFactory → getRepositoryFragments()
→ 查询方法解析器:QueryLookupStrategy → resolveQuery()

→ 最终使用的是:PartTreeJpaQuery 或 StringQuery

核心逻辑: Spring Data 通过方法名 findByName 解析出一个 JPQL 查询,形如:

SELECT u FROM User u WHERE u.name = :name

4️⃣ 构造查询并执行:调用 EntityManager.createQuery(...)

SimpleJpaRepository.findByName() → JpaQueryExecution → AbstractJpaQuery.doExecute()

→ entityManager.createQuery(jpql).setParameter("name", "Tom").getResultList();

5️⃣ Hibernate 接管 EntityManager 调用

Spring 使用的是 Hibernate 实现的 EntityManager,即 HibernateEntityManager(已在 5.x 中被合并到 SharedEntityManagerCreator 中)。

SharedEntityManagerCreator.invoke()
→ HibernateQueryImpl.getSingleResult()

内部使用 Hibernate 的核心类:

  • Session(Hibernate 的核心)
  • QueryImpl
  • SQL 生成器(AST Parser 或 CriteriaQuery)

Hibernate 将 JPQL 转换为 SQL,并执行 JDBC 操作。

6️⃣ Hibernate 执行 SQL 并返回结果

org.hibernate.loader.Loader → doQuery()
→ ResultSet → 实体映射器(EntityTuplizer)→ 实例化对象并返回

最终得到的实体对象将封装在 List 中返回给 SimpleJpaRepository,你拿到结果。

总结流程图

你调用方法:
   ↓
userRepository.findByName()
   ↓
SimpleJpaRepository
   ↓
QueryLookupStrategy → JPQL
   ↓
EntityManager.createQuery(...)
   ↓
Hibernate 解析 JPQL → SQL
   ↓
JDBC 查询
   ↓
ResultSet → 实体映射
   ↓
返回 List<User>

建议调试入口(关键类)

类名功能
SimpleJpaRepository核心实现类
QueryLookupStrategy方法解析器
JpaQueryFactory / PartTreeJpaQuery动态生成查询
SharedEntityManagerCreatorSpring 提供的 EntityManager 代理
org.hibernate.query.QueryImplHibernate 具体执行 SQL 的入口
org.hibernate.loader.Loader负责加载和映射数据库数据

我们可以使用 IDEA 或 Eclipse,可以通过设置断点进入这些类进行逐步调试。
也可以启用 Hibernate SQL 日志,看到真实 SQL:

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true