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
相关产品推荐
相关产品推荐

