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

Spring Boot整合H2数据库findAll()返回空、按ID查询空白问题

问题根因
  • 配置冲突+内存库特性导致空表:你使用的是H2内存数据库,表结构和数据仅在应用运行时存在,重启后会完全清空。同时配置中spring.jpa.hibernate.ddl-auto=none禁用了Hibernate自动根据实体类创建/更新表结构的能力,且你没有配置schema.sql/data.sql初始化脚本,应用启动后PERSON表要么不存在,要么是空表,查询自然返回空结果。另外你配置的spring.jpa.generate-ddl=true会被ddl-auto=none覆盖,完全不生效。
  • 实体类映射不匹配:你实体类中state1字段绑定的数据库列名是state1,和你实际表结构中的state列名不一致,会导致Hibernate查询时无法正确映射字段数据。且字段名state1和对应的getter/settergetState()/setState()名称不匹配,会让Jackson序列化/反序列化时把属性识别为state,如果前端传state1参数会绑定失败,写入的数据该字段为null。
  • 接口逻辑缺陷:getPersonById方法查询不到数据时直接返回null,Spring MVC处理null返回值不会输出任何JSON内容,最终接口返回空白响应。另外新增数据时前端一般不会传自增ID,此时entity.getId()为null,直接调用findById(null)会抛出参数异常,导致你根本无法通过接口成功写入数据,库中始终无数据。
修复方案
  1. 修正数据库配置,去掉冲突项,开发环境直接让Hibernate自动建表即可:
spring.datasource.url=jdbc:h2:mem:person;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# 启动时自动根据实体创建表,开发环境适用,需要保留表结构可改为update
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.defer-datasource-initialization=true

如果要自己维护建表SQL,就在src/main/resources下新建schema.sql写建表语句、data.sql写初始化数据,保持ddl-auto=none即可。

  1. 修正实体类映射,统一字段名避免序列化问题:
@Entity
@Table(name="PERSON")
public class PersonEntity {

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

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(name="city")
    private String city;

    // 统一字段名和列名、getter/setter命名
    @Column(name="state")
    private String state;

    @Column(name="zip")
    private int zip;

    // 所有getter/setter对应字段名生成即可
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getFirstName() { return firstName; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    public String getLastName() { return lastName; }
    public void setLastName(String lastName) { this.lastName = lastName; }
    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }
    public String getState() { return state; }
    public void setState(String state) { this.state = state; }
    public int getZip() { return zip; }
    public void setZip(int zip) { this.zip = zip; }
}

注:实体类字段建议改为private修饰,符合Java封装规范。

  1. 修复Service层逻辑漏洞,避免空指针和空响应:
@Service
public class PersonService {

    @Autowired
    PersonRepository personRepository;

    public PersonEntity createOrUpdateEmployee(PersonEntity entity) {
        // 新增场景id为null,直接保存
        if (entity.getId() == null) {
            return personRepository.save(entity);
        }
        // 更新场景先查库,不存在则直接新增
        return personRepository.findById(entity.getId()).map(existPerson -> {
            existPerson.setFirstName(entity.getFirstName());
            existPerson.setLastName(entity.getLastName());
            existPerson.setCity(entity.getCity());
            existPerson.setState(entity.getState());
            existPerson.setZip(entity.getZip());
            return personRepository.save(existPerson);
        }).orElseGet(() -> personRepository.save(entity));
    }
    
    public List<PersonEntity> getAll() {
        // 空结果直接返回空列表即可,无需额外判断
        return personRepository.findAll();
    }

    public PersonEntity getPersonById(Long id) {
        // 查询不到直接返回404状态,不要返回null
        return personRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "对应ID的人员不存在"));
    }
}

需要额外导入依赖类:org.springframework.web.server.ResponseStatusException、org.springframework.http.HttpStatus。

  1. 验证流程
  • 启动应用后访问H2控制台确认PERSON表字段和实体映射一致
  • 先调用POST /person接口传入测试参数写入数据
  • 再调用GET /people、GET /people/{id}接口即可正常返回数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 06:01:43