You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DataJpaTests执行时无法创建H2数据库表问题求助

SpringBoot DataJpa测试报错:找不到Company表(数据库为空)

我的SpringBoot项目使用MariaDB,正常运行模式下JPA功能正常,但执行DataJpa的JUnit测试时,出现错误提示:"找不到Company表(数据库为空)"。


生产环境配置(application.properties)

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mariadb://localhost:3306/app
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.show-sql= true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.properties.hibernate.format_sql=true
spring.data.rest.base-path=/app

测试环境配置(application-test.properties)

# must actually be named application-test.properties ;-)
# Enable H2 console
spring.h2.console.enabled=true

# H2 console path
spring.h2.console.path=/h2-console

# Configure H2 database
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:testdb;MODE=MYSQL;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=sa
spring.datasource.password=

# Configure JPA and Hibernate
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true

JUnit测试代码

package ch.wiss.unternehmensliste.repository;

import ch.wiss.unternehmensliste.model.Company;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.annotation.Rollback;

import java.util.List;
import java.util.Optional;

@DataJpaTest
class CompanyRepositoryTest {
    @Autowired
    private TestEntityManager entityManager;
    @Autowired
    CompanyRepository companyRepository;

    /**
     * JUnit test for saving a Company
     */

    @Test
    public void saveCompanyTest(){
        Company company = new Company("Microsoft", "www.microsoft.com", "Zürich");
        companyRepository.save(company);

        Assertions.assertThat(company.getId()).isGreaterThan(0);
    }
    
}

问题排查与解决方案

核心原因

  1. @DataJpaTest 默认会替换数据源,若未指定激活测试配置,会忽略自定义的application-test.properties
  2. H2数据库的MySQL模式适配存在细节问题,导致DDL自动建表失败
  3. 实体类Company可能缺少必要JPA注解,Hibernate无法识别生成表结构

具体解决步骤

  1. 强制加载测试配置
    在测试类上添加@ActiveProfiles("test"),明确指定使用测试环境配置:

    @DataJpaTest
    @ActiveProfiles("test") // 新增该行
    class CompanyRepositoryTest {
        // 原有代码不变
    }
    
  2. 修正H2连接URL参数
    调整URL解决表名大小写适配问题:

    spring.datasource.url=jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_LOWER=TRUE;DB_CLOSE_ON_EXIT=FALSE
    

    新增DATABASE_TO_LOWER=TRUE,避免H2生成的表名与实体类映射不匹配。

  3. 验证实体类JPA注解
    确保Company类添加了必要注解(Spring Boot 3+用jakarta.persistence,旧版本用javax.persistence):

    import jakarta.persistence.*;
    
    @Entity
    @Table(name = "company") // 明确指定表名,避免大小写歧义
    public class Company {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
        private String website;
        private String location;
    
        // 构造方法、getter、setter
    }
    
  4. 调整DDL策略(可选)
    将create改为create-drop,确保每次测试都重建表:

    spring.jpa.hibernate.ddl-auto=create-drop
    
  5. 开启日志排查(可选)
    添加日志配置,查看Hibernate建表语句执行情况:

    logging.level.org.hibernate.SQL=DEBUG
    logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
    

内容的提问来源于stack exchange,提问作者Miggtor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:13:17