# Hibernate 调试器

> For the complete documentation index, see [llms.txt](https://www.jetbrains.com.cn/help/idea/llms.txt).

[安装 Hibernate Debugger 插件](jetbrains://tool/plugin/install?id=com.intellij.hibernate.debugger&tool=IU)

Hibernate 调试器   是一个 IntelliJ IDEA 插件，可用于检查应用程序中运行的数据库查询，并将其追溯到代码中触发这些查询的位置。 它适用于直接使用 [Hibernate](hibernate.html) 6 或更高版本，或通过 [Spring](spring-support.html) 等框架使用它的应用程序。

![正在运行的 Spring 调试器会话中的 Hibernate Debugger 日志条目](https://resources.jetbrains.com.cn/help/img/idea/2026.3/hibernate_debugger_spring.png)

可以使用 Hibernate Debugger 执行以下调试任务：

* 检查特定操作触发的 HQL 语句，以及 Hibernate 因此发送到数据库的 SQL。

* 查找慢查询和潜在的 N+1 问题。

* 定位触发特定查询的代码。

* 在 IDE 中重新运行捕获的 HQL 和 SQL。

* 探索应用程序连接到的数据库。

> **Note:**
> 本主题仅介绍   Hibernate 调试器   专有的功能。 要了解与框架无关的调试器功能，请参阅 [调试代码](debugging-code.html)。

## 前提

* 已安装并启用以下插件： * [Hibernate Debugger](https://plugins.jetbrains.com/plugin/34028) * [Jakarta EE：Persistence (JPA)](https://plugins.jetbrains.com/plugin/20202)（捆绑） * 数据库工具和 SQL（捆绑） 要检查插件是否已启用，请打开 设置 （ `Ctrl+Alt+S` (Windows), `⌘ Comma` (macOS), `⌘ Comma` (IntelliJ IDEA Classic (macOS)), `⌘ Comma` (macOS System Shortcuts), `Ctrl+Alt+S` (XWin), `Ctrl+Alt+S` (GNOME), `Ctrl+Alt+S` (KDE), `Ctrl+Alt+S` (Emacs), `Ctrl+Alt+S` (Sublime Text), `⌘ Comma` (Sublime Text (macOS)), `Ctrl+Alt+S` (Visual Studio), `⌘ Comma` (Visual Studio (macOS)), `Ctrl+Alt+S` (NetBeans), `Ctrl+Alt+S` (Eclipse), `⌘ Comma` (Eclipse (macOS))）并转到 插件 。 [在 IDE 中打开](jetbrains://tool/settings?name=Plugins&tool=IU)

* 构建文件（ `pom.xml` 或 `build.gradle` ）包含 Hibernate 6 或更高版本。 常见的添加方式包括： * ![Spring 框架徽标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/spring.icons.expui.spring.svg) Spring Boot starter：Spring Boot 3.0 或更高版本中的 `spring-boot-starter-data-jpa` [了解如何将 starter 添加到 Spring Boot 项目。](spring-boot.html#add-starter) * 直接依赖项： `hibernate-core` 版本 6 或更高版本 [了解如何将 Hibernate 添加到项目。](hibernate.html#add-to-existing-project)

## 记录并检查数据库查询

Hibernate Debugger 在 [IntelliJ IDEA 调试器](debugging-code.html) 内运行。 每当应用程序在调试会话期间通过 Hibernate 运行查询时，插件都会在调试器控制台中记录其相关信息。 日志会显示已执行的 SQL 和任何相关的 HQL，以及执行时间、事务 ID 和触发查询的代码等运行时详细信息。

查询记录默认开启。

Procedure: 使用 Hibernate Debugger 检查查询

1. [开始调试会话。](starting-the-debugger-session.html)

2. 在应用程序中，执行与数据库交互的操作。

3. 转到 [Debug](debug-tool-window.html) 工具窗口并打开   控制台   选项卡。

4. 查找所执行操作的 Hibernate Debugger 日志条目。 每个条目都会折叠为一个突出显示的行，并显示已执行的 SQL 语句。

![Debug 工具窗口的 Console 选项卡中突出显示 Hibernate Debugger 条目的行](https://resources.jetbrains.com.cn/help/img/idea/2026.3/hibernate_debugger_spring_collapsed_queries.png)

> **Tip:**
> 最新的日志条目显示在控制台底部。 要跳转到这些条目，请点击左侧工具栏中的 ![向下滚动图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.general.scrollDown.svg)   滚动到末尾  。

5. 点击突出显示的行以打开日志条目。

![展开的 Hibernate Debugger 日志条目](https://resources.jetbrains.com.cn/help/img/idea/2026.3/hibernate_debugger_spring.png)

要了解如何解读日志条目，请参阅 [参考：Hibernate Debugger 日志条目](#hibernate-debugger-reference)。

Procedure: 筛选已记录的查询

1. 调试会话运行时，转到   调试   工具窗口并打开   控制台   选项卡。

2. 在调试器工具栏中，点击 ![Hibernate Debugger 图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.hibernate.debugger.ide.frontend.icons.sqlLog.svg)   SQL 日志设置和筛选器  。

3. 选择一个或多个筛选器：

* 仅显示疑似 N+1 查询 ：仅显示来自疑似存在 N+1 问题的事务的查询。 随后可以 [在代码中跟踪其来源](#identify-nplusone-queries)。

* 按时长筛选 ：指定以毫秒为单位的最短时长，以仅显示执行时间达到或超过该时长的查询。

* 按事务使用筛选器 ：指定事务 ID，以仅显示在此事务中执行的查询。

如果选择多个筛选器，则只会显示与所有筛选器都匹配的日志条目。 筛选器应用于当前调试会话，并在关闭会话选项卡时清除。

Procedure: 识别 N+1 查询并在代码中跟踪其来源

N+1 查询问题是使用对象关系映射（ORM）框架的应用程序中的常见性能问题。 当应用程序运行一个查询来提取记录列表，然后又为每条记录运行单独的查询来提取相关数据时，就会出现此问题。

Hibernate Debugger 会检测存在潜在 N+1 查询的事务，并允许筛选掉其他事务中的查询。

1. 开始调试会话。

2. 在应用程序中，调用要检查是否存在 N+1 查询的操作。

3. 转到   调试   工具窗口并打开   控制台   选项卡。

4. 在调试器工具栏中，点击 ![Hibernate Debugger 图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.hibernate.debugger.ide.frontend.icons.sqlLog.svg)   SQL 日志设置和筛选器   并选择   仅显示疑似 N+1 查询  。

5. 查找共享相同事务 ID 和 SQL 查询的突出显示行。

![筛选疑似 N+1 查询后，具有相同事务 ID 和 SQL 查询的突出显示 Hibernate Debugger 日志条目](https://resources.jetbrains.com.cn/help/img/idea/2026.3/hibernate_debugger_spring_nplusone_collapsed.png)

6. 点击其中一个突出显示的行以打开其日志条目，然后展开其 [Invocation stack](#invocation-stack) 部分。 其中包含导致重复查询执行的方法调用序列。

![Debug 工具窗口中展开了疑似 N+1 查询的 Invocation stack 部分](https://resources.jetbrains.com.cn/help/img/idea/2026.3/hibernate_debugger_spring_nplusone_expanded.png)

7. 找到以项目代码中的文件名和行号结尾的最上方堆栈行（不是库或框架生成的代码），然后点击它们。

IntelliJ IDEA 会在代码触发查询的行处打开文件。 检查该方法、其周围代码以及调用它的方法，以找出查询反复运行的原因。

> **Tip:**
> N+1 查询问题通常由以下编码模式导致：
>
>
>
> * 在循环内运行查询
>
> * 在循环中使用相关数据，但未在第一个查询中提取这些数据
>
> * 提取具有 `@ManyToOne` 或 `@OneToOne` 关联的实体，但未在同一查询中提取这些关联
>
> * 将实体与第一个查询未提取的相关数据一起转换为 JSON 或 DTO

Procedure: 停止记录查询

1. 调试会话运行时，转到   调试   工具窗口。

2. 在调试器工具栏中，点击 ![Hibernate Debugger 图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.hibernate.debugger.ide.frontend.icons.sqlLog.svg)   SQL 日志设置和筛选器   并清除   记录数据库查询日志   选项。

![Hibernate Debugger SQL Log Settings and Filters 框中已清除 Log database queries 选项](https://resources.jetbrains.com.cn/help/img/idea/2026.3/hibernate_debugger_spring_stop_logging.png)

关闭查询记录会应用于项目中的所有调试会话。 可以随时再次选择   记录数据库查询日志   将其重新开启。

## 重新运行捕获的查询

可以重新运行 Hibernate Debugger 捕获的查询，而无需在应用程序中再次触发这些查询。 HQL 语句会在 [JPA Console](using-jpa-console.html) 中重新运行，SQL 语句会在 [query console](query-consoles.html) 中重新运行。

> **Warning:**
> 重新运行 HQL 语句所做的更改会自动提交，且无法回滚。 对于 SQL 语句，这取决于查询控制台的 [transaction mode](configuring-database-connections.html#transaction-mode)。

Procedure: 重新运行 HQL 查询

例如，当想要检查查询提取了哪些记录、比较应用程序将更改提交到数据库前后的结果，或将其与序列中的其他查询分开运行时，重新运行 HQL 会很有用。

1. [打开 Hibernate Debugger 日志条目](#inspect-debugger-logs)，以重新运行所需查询。

2. 点击 HQL 旁边的 ![绿色三角形图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.run.run.svg)   执行查询  。 如果某些参数值无法恢复，系统会提示指定这些值。

JPA 控制台   会执行查询并显示其结果。

![从 JPA Console 中的 Hibernate Debugger 日志重新运行查询的结果](https://resources.jetbrains.com.cn/help/img/idea/2026.3/rerun_query_jpa_console.png)

3. （可选）使用不同的参数值重新运行查询：

1.

从结果选项卡切换到控制台选项卡。

[详细了解 JPA Console 布局。](using-jpa-console.html#jpa-console-reference)

2.  在查询工具栏中，点击 ![参数图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/app.expui.nodes.parameter.svg)   查看参数  。 这会在控制台右侧打开一个包含参数值的窗格。

3.  编辑参数值，然后按 `Ctrl+Enter` (Windows), `⌘ ⏎` (macOS), `⌘ ⏎` (IntelliJ IDEA Classic (macOS)), `⌘ ⏎` (macOS System Shortcuts), `Ctrl+Enter` (XWin), `Ctrl+Enter` (GNOME), `Ctrl+Enter` (KDE), `Ctrl+Enter` (Emacs), `Ctrl+Enter` (Sublime Text), `⌘ ⏎` (Sublime Text (macOS)), `Ctrl+Enter` (Visual Studio), `⌘ ⏎` (Visual Studio (macOS)), `Ctrl+Enter` (NetBeans), `Ctrl+Enter` (Eclipse), `⌘ ⏎` (Eclipse (macOS)) 重新运行查询。

Procedure: 重新运行 SQL 查询

当需要检查 Hibernate 在延迟加载期间提取了哪些记录，或慢查询直接针对数据库运行时需要多长时间时，重新运行 SQL 会很有用。

1. [打开 Hibernate Debugger 日志条目](#inspect-debugger-logs)，以重新运行所需查询。

2. 点击 SQL 旁边的 ![绿色三角形图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.run.run.svg)   执行查询  。

特定于数据库的查询控制台会执行查询， [服务](services-tool-window.html#db-sessions)工具窗口会显示结果。

![从 Services 工具窗口中的 Hibernate Debugger 日志重新运行查询的结果](https://resources.jetbrains.com.cn/help/img/idea/2026.3/rerun_query_query_console.png)

3. （可选）使用不同的参数值重新运行查询：

1.  在编辑器中，转到 IntelliJ IDEA 打开的查询控制台标签页。 SQL 查询已在那里，并带有原始参数值。

2.  编辑参数值，然后按 `Ctrl+Enter` (Windows), `⌘ ⏎` (macOS), `⌘ ⏎` (IntelliJ IDEA Classic (macOS)), `⌘ ⏎` (macOS System Shortcuts), `Ctrl+Enter` (XWin), `Ctrl+Enter` (GNOME), `Ctrl+Enter` (KDE), `Ctrl+Enter` (Emacs), `Ctrl+Enter` (Sublime Text), `⌘ ⏎` (Sublime Text (macOS)), `Ctrl+Enter` (Visual Studio), `⌘ ⏎` (Visual Studio (macOS)), `Ctrl+Enter` (NetBeans), `Ctrl+Enter` (Eclipse), `⌘ ⏎` (Eclipse (macOS)) 重新运行查询。

## 调试时访问数据库

当查询结果与预期不符时，原因可能不在代码中，而在数据中。 为了帮助检查二者，Hibernate Debugger 会将调试会话中的数据库连接添加到 [数据库](database-tool-window.html)工具窗口。

![Database 工具窗口显示了在调试器会话期间添加的数据源。 工具窗口中的顶层节点显示运行配置名称，数据源本身在方括号中带有调试注释。](https://resources.jetbrains.com.cn/help/img/idea/2026.3/hibernate_debugger_spring_data_source.png)

以下是可在 IntelliJ IDEA 中使用调试会话中的 [数据源](managing-data-sources.html) 的几个示例：

* 在 [数据编辑器和查看器](data-editor-and-viewer.html) 中查找、添加、编辑或删除数据库记录。

* 在 [查询控制台](query-consoles.html) 或 [JPA 控制台](using-jpa-console.html) 中针对数据库执行查询。

* 通过 [对数据库进行逆向工程](reverse-engineering.html)为现有表创建实体类。

* 通过生成 [Flyway 迁移](flyway.html) 或 [Liquibase 变更日志](liquibase.html)，使数据库架构与实体类保持一致。

Hibernate Debugger 创建的数据源会在调试会话结束时被移除。 若要永久保留数据源，请在会话仍在运行时创建其副本。

Procedure: 调试会话结束后保留数据源

1. 调试会话运行时，转到   数据库   工具窗口。

2. 查找以调试会话命名的文件夹，并选择要保留的数据源。

3. 右键点击数据源并选择  `复制/粘贴 | ![复制图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.general.copy.svg) 副本` 。

* 或者按 `Ctrl+D` (Windows), `⌘ D` (macOS), `⌘ D` (IntelliJ IDEA Classic (macOS)), `⌘ D` (macOS System Shortcuts), `Ctrl+D` (XWin), `Ctrl+D` (GNOME), `Ctrl+D` (KDE), `Meta+D` (Emacs), `Ctrl+Shift+D` (Sublime Text), `⌘ ⇧ D` (Sublime Text (macOS)), `Ctrl+D` (Visual Studio), `⌘ D` (Visual Studio (macOS)), `Ctrl+D` (NetBeans), `Ctrl+D` (Eclipse), `Ctrl+D` (Eclipse (macOS))。

4. [数据源和驱动程序](data-sources-and-drivers-dialog.html)对话框将打开。 如有需要，请重命名数据源或调整其连接详细信息。

5. 点击   OK   以保存副本。

6. 复制的数据源会放置在与原始数据源相同的文件夹中。 若要防止副本被移除，请右键点击它并选择  `移动 | 移至顶层` 。

## 参考：Hibernate Debugger 日志条目

![带有框架标记日志不同组成部分的 Hibernate Debugger 日志条目图像](https://resources.jetbrains.com.cn/help/img/idea/2026.3/hibernate_debugger_spring_reference.png)

Hibernate Debugger 日志条目包含以下部分：

1.  [标头](#header)

2.  [会话 ID](#session-id)

3.  [HQL 语句](#hql-statement)

4.  [SQL 语句](#sql-statement)

5.  [调用堆栈](#invocation-stack)

该插件还会向调试器添加一个工具栏图标 (6)： ![Hibernate Debugger 图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.hibernate.debugger.ide.frontend.icons.sqlLog.svg) [SQL 日志设置和筛选器](#settings-and-filters)，用于筛选日志条目并更改其显示方式。

### 标头

日志条目标头包含以下信息：

1.  Hibernate Debugger 捕获查询时的时间戳。 它使用带 UTC 偏移量的 ISO 8601 格式的本地时间。

2.  执行查询所花费的时间。

3.  执行查询所在的 [Hibernate 事务](https://docs.hibernate.org/orm/current/javadocs/org/hibernate/Transaction.html) 的 ID。 此值由调试器分配。 短横线表示 Hibernate Debugger 无法确定查询属于哪个事务。

可以点击 ID 并选择   按此事务使用筛选器  ，筛选日志条目以仅显示来自此事务的查询。

### 会话 ID

此 ID 标识将查询发送到数据库的 [Hibernate 会话](https://docs.hibernate.org/orm/current/javadocs/org/hibernate/Session.html)。 它由 Hibernate 分配。

短横线表示 Hibernate Debugger 无法确定是哪个会话发送了查询。

### HQL 语句

这是应用程序交给 Hibernate，并由 Hibernate 转换为下方 SQL 语句的查询。 在代码中，查询可以来自仓库方法、查询字符串 (HQL、JPQL、JDQL) 或 [Jakarta Persistence Criteria API](https://jakarta.ee/learn/docs/jakartaee-tutorial/current/persist/persistence-criteria/persistence-criteria.html)，但此处始终显示为 HQL 语句。

> **Note:**
> 对于原生 SQL 查询，以及 Hibernate 独立于其他查询执行的 SQL (例如，在原始查询之后延迟提取相关数据时)，不会显示此部分。

如果 HQL 包含参数，其值会按以下格式之一列在单独一行：

* `name: Type = value` ：命名参数

* `?1: Type = value` ：位置参数

* `__param_0: Type = value` ：生成的参数 (例如，派生自仓库方法名称)

* `?unknown: Type = value` ：无法确定名称的参数

* `name: <unbound>` ：执行 HQL 时没有值的参数

![绿色三角形图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.run.run.svg)   执行查询   图标可使用相同的参数值 [在 JPA 控制台中重新运行 HQL 语句](#rerun-HQL-query)。 如果图标带有错误指示器 ( ![红色 X 标记](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.runConfigurations.invalidConfigurationLayer.svg))，则表示某些参数值无法传递给控制台。 在这种情况下，控制台会在重新运行 HQL 之前提示输入缺失的值。

> **Note:**
> 某些 HQL 查询会使 Hibernate 执行多个 SQL 查询 (例如，一个用于加载实体的查询以及用于预先提取其相关数据的额外查询)。 对于额外查询，此部分称为   由 HQL 触发  ，并且不包含参数值或用于重新运行查询的图标。

### SQL 语句

这是 Hibernate 发送到数据库的 SQL 语句。 它可以由 Hibernate 从上方的 HQL 转换而来，由 Hibernate 自行生成，或在代码中编写为原生 SQL 查询。

如果语句包含参数，其值会显示在语句内。

![绿色三角形图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.run.run.svg)   执行查询   图标可使用相同的参数值 [在查询控制台中重新运行 SQL 语句](#rerun-SQL-query)。

### 调用堆栈

调用堆栈显示了导致 Hibernate 将 SQL 语句发送到数据库的方法调用。 与任何 Java 堆栈跟踪一样，最近的调用位于顶部。 库代码中的调用 (例如 Hibernate 或 Spring) 默认处于收起状态。

调用堆栈中的每一行表示一次方法调用。 例如，请考虑这个简化的堆栈：

```JAVA_STACKTRACE
at com.example.library.BookRepository.findByTitle(BookRepository.java:31)
at com.example.library.BookService.searchBooks(BookService.java:24)
at com.example.library.BookController.listBooks(BookController.java:18)

```

高亮显示的行表示对  `searchBooks()`  的调用。 示例堆栈提供了关于它的以下详细信息：

* `searchBooks()` 由 `BookController.listBooks()` 调用。

* 它在 `BookService` 类中声明，该类属于 `com.example.library` 软件包。

* 它在 `BookService.java` 源文件中实现。

* 在该文件的第 24 行，它调用了 `BookRepository.findByTitle()` 。

大多数堆栈行以文件名和行号结尾，用于显示此方法调用下一个方法的位置。 可以点击它们导航到编辑器中的该调用。 如果某一行改为以  `Unknown Source`  或  `<generated>`  结尾，则该调用通常来自框架直接以编译形式生成的代码，因此没有对应的源文件。

#### 来自 Spring Data JPA 应用程序的示例

```JAVA_STACKTRACE
Invocation stack: <36 hidden frames>
    at com.example.library.BookRepository.findByTitle(Unknown Source)
    at com.example.library.BookService.searchBooks(BookService.java:24) <14 hidden frames>
    at com.example.library.BookService$$SpringCGLIB$$0.searchBooks(<generated>)
    at com.example.library.BookController.listBooks(BookController.java:18) <53 hidden frames>

```

在此示例中，调用序列如下 (从下往上阅读)：

1.  库代码中的调用链 (收起为  `<53 hidden frames>` ) 导致项目代码中调用了  `BookController.listBooks()` 。

2.   `BookController.listBooks()`  调用了  `BookService.searchBooks()` 。

1.  调用进入  `BookService$$SpringCGLIB$$0` 。 这是 Spring 在运行时生成的代理，因此显示  `<generated>`  而不是文件名。

2.  该代理启动了 Spring 库代码中的调用链 (收起为  `<14 hidden frames>` )，最终调用了  `BookService.searchBooks()` 。

3.

`BookService.searchBooks()`  调用了  `BookRepository.findByTitle()` 。

调用进入 Spring Data 提供的方法实现。 此实现是在运行时生成的，因此显示  `Unknown Source`  而不是文件名。

4.   `findByTitle()`  的实现启动了 Spring 和 Hibernate 库代码中的调用链 (收起为  `<36 hidden frames>` )，最终导致 Hibernate 将 SQL 语句发送到数据库。

### 设置和筛选器

|  条目  |  描述  |
| --- | --- |
|    记录数据库查询日志    |     开启或关闭查询日志记录。      > **Note:** > 此选项会影响当前项目中的所有调试会话，包括之后启动的调试会话。      有关更多信息，请参见 [停止记录查询](#stop-logging-queries)。     |
|    语句格式设置    |     更改语句在调试器控制台中的显示方式：        * 对于 HQL 语句，这会将每个子句 (例如 `select` 、 `从` 或 `where` ) 移到新行，并将生成的别名替换为实体的首字母。    * 对于 SQL 语句，这会应用 IDE 中配置的 [SQL 代码样式](configure-the-sql-code-style.html)。    |
|    仅显示疑似 N+1 查询    |     仅显示来自疑似存在 N+1 问题的事务的查询，即同一查询会被反复执行。       有关更多信息，请参见 [识别 N+1 查询并在代码中跟踪其来源](#identify-nplusone-queries)。     |
|    按时长筛选    |     指定最短持续时间 (毫秒)，以仅显示执行时间达到或超过此时长的查询。     |
|    按事务使用筛选器    |     指定事务 ID，以仅显示在此事务中执行的查询。     |

