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

Spring Boot NonUniqueResultException查询异常排查与代码修正求助

解决Spring Boot中javax.persistence.NonUniqueResultException异常

问题原因

你遇到的javax.persistence.NonUniqueResultException: query did not return a unique result: 2异常,核心问题出在这几点:

  • 数据库中存在两条手机号相同的客户记录,但代码逻辑期望返回唯一结果
  • Repository方法命名和返回类型不匹配:findAllByMobileEquals语义上应返回多条数据,但你用Optional<Customer>接收,Spring Data JPA会强制校验结果唯一性,查到多条就抛出异常
  • 虽然实体类给mobile字段加了unique=true,但如果是先插入重复数据再加的注解,数据库不会自动清理重复数据,唯一约束也不会生效

修复步骤

1. 清理数据库重复数据

先手动清理数据库中重复的手机号记录,保留一条即可。执行以下SQL:

-- 删除重复的手机号记录,保留ID最小的那条
DELETE FROM customer WHERE customer_id NOT IN (
    SELECT MIN(customer_id) FROM customer GROUP BY mobile
);

同时手动给mobile字段创建唯一索引,避免后续插入重复数据:

CREATE UNIQUE INDEX idx_customer_mobile ON customer(mobile);

2. 修正Repository方法

把Repository中的查询方法改成符合业务语义的命名,因为手机号是唯一的,用findByMobile即可,返回Optional<Customer>:

// CustomerRepo
Optional<Customer> findByMobile(int mobile);

如果业务后续允许手机号重复(不推荐),可以改成返回List<Customer>:

List<Customer> findAllByMobile(int mobile);

3. 调整Service层逻辑(可选,仅当返回List时)

如果改成返回List<Customer>,Service层需要处理多条结果的情况:

@Override
public CustomerDTO getCustomerphone(int mobile) {
    List<Customer> customers = customerRepo.findAllByMobile(mobile);
    if(customers.isEmpty()) {
        return null;
    } else if(customers.size() > 1) {
        throw new RuntimeException("数据库中存在重复的手机号记录");
    } else {
        return modelMapper.map(customers.get(0), CustomerDTO.class);
    }
}

更推荐用findByMobile的方式,符合手机号唯一的业务设计。

4. 验证功能

重启项目后,调用/get-by-active-phone?mobile=xxx接口,即可正常返回唯一的客户信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:42:47