知識庫 / Spring / Spring Boot RSS 訂閱

修復 Spring Boot H2 異常:“Schema 未找到”

Persistence,Spring Boot
HongKong
4
11:05 AM · Dec 06 ,2025

1. 概述

H2 是一款開源 SQL 數據庫,常用於 Java 社區的測試目的。由於其內存數據庫的特性,它不會將任何數據持久化到磁盤,因此速度非常快。

我們可能會在將其與 Spring Boot 集成時遇到“Schema not found”錯誤消息。在本教程中,我們將探討其原因,並研究兩種不同的解決方案。

2. 瞭解原因

默認情況下,H2 模式是 PUBLIC。如果我們將不使用 PUBLIC 模式的 JPA 實體類映射到 H2 中,則必須確保在 H2 中創建該模式。Spring Boot 在目標模式不存在時,會報告錯誤消息“Schema not found”。

為了模擬該場景,讓我們在 Spring Boot 應用程序中創建以下實體類和存儲庫。 @Table 註解指定實體映射到 test 模式中的 student 表的表映射詳細信息。

@Entity
@Table(name = "student", schema = "test")
public class Student {
    @Id
    @Column(name = "student_id", length = 10)
    private String studentId;

    @Column(name = "name", length = 100)
    private String name;

    // constructor, getters and setters
}
public interface StudentRepository extends JpaRepository<Student, String> {
}

接下來,我們啓動 Spring Boot 應用程序並訪問存儲庫。 我們會遇到一個異常,指示模式不存在。我們可以通過集成測試來驗證這一點:

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = SampleSchemaApplication.class)
class SampleSchemaApplicationIntegrationTest {
    @Autowired
    private StudentRepository studentRepository;

    @Test
    void whenSaveStudent_thenThrowsException() {
        Student student = Student.builder()
          .studentId("24567433")
          .name("David Lloyds")
          .build();

        assertThatThrownBy(() -> studentRepository.save(student))
          .isInstanceOf(InvalidDataAccessResourceUsageException.class);
    }
}

在測試執行過程中,您將在控制枱中看到以下錯誤消息:

org.hibernate.exception.SQLGrammarException: could not prepare statement [Schema "TEST" not found; SQL statement:
select s1_0.student_id,s1_0.name from test.student s1_0 where s1_0.student_id=? [90079-214]] [select s1_0.student_id,s1_0.name from test.student s1_0 where s1_0.student_id=?]

3. 通過數據庫 URL 創建 Schema

為了解決此問題,應用程序啓動時必須創建相應的 Schema。有兩的不同方法可以實現。

第一種方法是在建立數據庫連接時創建數據庫 Schema。 H2 數據庫 URL 允許我們在客户端通過 INIT 屬性連接到數據庫時執行 DDL 或 DML 命令。在 Spring Boot 應用程序中,我們可以將 spring.datasource.url 屬性定義在 application.yaml 中:

spring:
  jpa:
    hibernate:
      ddl-auto: create
  datasource:
    driverClassName: org.h2.Driver
    url: jdbc:h2:mem:test;INIT=CREATE SCHEMA IF NOT EXISTS test

初始化DDL會創建schema,如果schema不存在。 這種方法專門為H2數據庫設計,可能無法在其他數據庫上使用。

這種方法通過數據庫URL創建schema,無需顯式創建表。 我們通過將 spring.jpa.hibernate.ddl-auto 屬性設置為 create,在YAML文件中實現,讓Hibernate自動創建schema。

4. 通過初始化腳本創建 Schema

我們採用的第二種方法是通用的,也可以應用於其他數據庫。通過一個初始化腳本創建所有數據庫組件,包括 Schema 和表。

Spring Boot 在執行初始化腳本之前會初始化 JPA 持久單元。因此,我們在 application.yaml 中顯式禁用 Hibernate 的自動 Schema 生成,因為我們的初始化腳本已經負責處理它:

spring:
  jpa:
    hibernate:
      ddl-auto: none

如果我們沒有通過將 ddl-auto 從 create 更改為 none,則在應用程序啓動時會遇到“Schema TEST 未找到”異常。 數據庫模式在 JPA 持久單元初始化期間尚未創建。

現在,我們可以將創建 test 模式和 student 表的 schema.sql 文件放在 resources 文件夾中:

CREATE SCHEMA IF NOT EXISTS test;

CREATE TABLE test.student (
  student_id VARCHAR(10) PRIMARY KEY,
  name VARCHAR(100)
);

Spring Boot 默認情況下,會在 resources 文件夾中查找 DDL 腳本 schema.sql 以在應用程序啓動期間初始化數據庫。

5. 結論

Schema not found” 異常是 Spring Boot 應用程序啓動時與 H2 數據庫集成時常見的錯誤。通過確保通過數據庫 URL 配置或初始化腳本創建模式,我們可以避免這些異常。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.