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

保存含嵌套对象的JSON至数据库时遇NonUniqueResultException错误求助

问题分析与解决方案

1. 异常直接原因:查询返回非唯一结果

NonUniqueResultException的核心原因是:
你用Optional<Debts>和Optional<Madeen>接收查询结果,但debtsRepository.findDebtsByPersonIdAndOrganization_id或madeenRepository.findByPersonId实际返回了2条数据。Optional仅支持0或1条结果,超出范围就会抛出异常。

修复方案:

  • 如果业务逻辑允许多条结果:将查询方法的返回类型改为List<Debts>/List<Madeen>,对应代码中用List接收。
  • 如果业务逻辑要求唯一结果:检查数据库中是否存在重复数据,或者修改查询条件(比如添加唯一约束字段),或改用findFirstByXXX类方法确保只返回第一条结果。

2. DTO设计错误:无法正确解析JSON数组

你的InvoicesDTO实现了List<InvoicesDTO>,这是完全错误的设计——这个类是单个发票项的DTO,不应该继承List接口。同时InvoiceDTO中用private InvoicesDTO invoices;无法正确接收JSON中的数组,会导致序列化/反序列化失败,也会影响后续遍历逻辑。

修复方案:

  • 重命名InvoicesDTO为InvoiceItemDTO(语义更准确),移除implements List<InvoicesDTO>。
  • 在InvoiceDTO中将invoices字段改为List<InvoiceItemDTO>类型,用于接收JSON数组。

修正后的代码示例:
InvoiceItemDTO

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class InvoiceItemDTO {
    @NotNull(message = "invoice Number can't be null")
    private String invoiceNumber;

    @NotNull(message = "invoiceAmount can't be null")
    private Double invoiceAmount; 
}

InvoiceDTO

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class InvoiceDTO {
  @NotNull(message = "PersonId can't be null")
  @PersonId
  private String personId;

  @NotNull(message = "invoiceDate can't be null")
  @PastOrPresent
  @JsonFormat(pattern = "yyyy-MM-dd")
  private LocalDate invoiceDate;

  private List<InvoiceItemDTO> invoices; // 改为List类型接收数组
}

3. 处理逻辑优化

修复DTO后,调整处理逻辑,同时增加空值判断避免空指针:

try {
    // 根据业务选择合适的查询返回类型
    List<Debts> debtsList = debtsRepository.findDebtsByPersonIdAndOrganization_id(invoiceDTO.getPersonId(), organization.get().getId());
    List<Madeen> madeenList = madeenRepository.findByPersonId(invoiceDTO.getPersonId());

    List<InvoiceItemDTO> invoicesDTO = invoiceDTO.getInvoices();
    // 增加空值判断
    if (invoicesDTO != null && !invoicesDTO.isEmpty()) {
        for (InvoiceItemDTO invoiceItem : invoicesDTO) {
            Debts newDebt = new Debts();
            newDebt.setPersonId(invoiceDTO.getPersonId());
            newDebt.setCreatedDate(LocalDate.now());
            newDebt.setUpdatedDate(invoiceDTO.getInvoiceDate());
            newDebt.setDebtAmount(invoiceItem.getInvoiceAmount());
            newDebt.setInvoiceNumber(invoiceItem.getInvoiceNumber());
            // 先判断organization是否存在,避免NoSuchElementException
            if (organization.isPresent()) {
                newDebt.setOrganization(organization.get());
                debtsRepository.save(newDebt);
            }
        }
    }
} catch (Exception e) {
    // 按需处理异常,比如日志记录、返回错误响应
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:40:50