当您只有 id 时创建映射实体

时间:2021-07-05 17:08:47

标签: java spring-boot jpa spring-data-jpa

老实说,我不确定如何表述问题标题,如果有人有建议,请告诉我。

我的用例是这样的,我有一个具有像这样的帐户属性的实体(这是为了避免混乱而清理的):

@Entity
@Table(name = "report_line", schema = "public")
public class ReportLine extends BaseReportLine {
  @ManyToOne
  @JoinColumn(name = "report_id")
  private Report report;

  @ManyToOne
  @JoinColumn(name = "account_id")
  private Account account;
}

但是只有一个帐户 ID/不同属性的 DTO:

public class ImportLineDto {
  public String groupName;
  public Integer position;
  public Integer parentPosition;
  public String accountId;
  public String name;
  public BigDecimal amount;
  public List<ImportLineDto> lines = new ArrayList<>();
}

我需要遍历/展平所有行,以便将其保存到 JPA 存储库,但有两个问题:

  1. 有没有办法只使用 accountId 创建表格行对象,而不必为每一行查找帐户,因为这会增加大量不必要的数据库调用。
  2. 在展平后,我应该如何处理每个表格对象上的“线条”?我应该将它们设置为空/空列表吗?
  3. 有没有更好的方法来做到这一点?这一次我可以真正更改代码

这是我目前所拥有的:

  private void saveReport(ImportedResult result) {
    Report report = new Report();
    ...
    report.setLines(getReportLinesFromDtoLines(result.lineItems.lines));
    ReportRepository.saveAndFlush(report);
  }

  private List<ReportLine> getReportLinesFromDtoLines(ImportLineDto lines) {
    List<ImportLineDto> flatLines = flatMapRecursive(lines).collect(Collectors.toList());
    List<ReportLine> reportLines = new ArrayList<>();

    for(ImportLineDto line: flatLines) {
      ReportLine reportLine = new ReportLine();
      reportLine.setItemText(line.name);
      reportLine.setAmount(line.amount);
      reportLine.setAccount(???);
      // how do I set the 'Account' property using the id only, without looking up each account?

      reportLines.add(reportLine);
    }

    return ReportLines;
  }

  public Stream<ImportLineDto> flatMapRecursive(ImportLineDto item) {
    if (item.lines == null) {
      return Stream.empty();
    }

    return Stream.concat(Stream.of(item), item.lines.stream()
        .flatMap(this::flatMapRecursive));
  }

跟进:

只是想说一下,如果 DTO accountId 不是表中的实际“id”字段,而是另一个自定义字段,我还有另一种情况,这可能吗?我仍然需要使用标准 ID 回答第一个问题。

1 个答案:

答案 0 :(得分:0)

您可以按照说明使用 entityManager.getReference here

reportLine.setAccount(entityManager.getReference(Account.class, line.accountId));