首页 > 解决方案 > Mapstruct 多对一映射

问题描述

我对 mapstruct 中的 @ManyToOne 映射有疑问。我有两张桌子

第一个:

@Entity
@Table(name = "members", schema = vsm)
public class MemberEntity{

    @Column(name = "id", nullable = false)
    protected Long id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "case_id", nullable = false)
    private CaseEntity case;
}

第二个:

@Entity
@Table(name = "cases", schema = vsm)
public class CaseEntity {

    @Column(name = "id", nullable = false)
    protected Long id;

    @Column(name = "description", nullable = false)
    protected String description;
}

我有一个这样的案例:

public class CasesDto{

    protected Long id;

    protected String description;

    private List<MemberDto> members;
}

和MemberDto 一样的实体。

我需要像这样使用 mapstruct 进行映射:

CasesDto mapToDto(CaseEntity entity);

我需要填写列表成员;但我不明白怎么做。

标签: javahibernateentitydtomapstruct

解决方案


您不能以这种方式简单地将其映射到 CasesDto。没有要映射到的集合List<MemberDto>您应该完全组成 CaseEntity,其中包括:

  @OneToMany(mappedBy = "cases")
  private List<MemberEntity> members = new ArrayList<>();

为了避免最坏的情况 N+1 问题(stackOverflow N+1),您应该正确配置 JPA(简短的 spring .yml 示例),这将允许您1 + Math.ceil({MembersAmount}/{default_batch_fetch_size})通过 ORM 执行查询:

spring:
  jpa:
    properties:
      hibernate:
        jdbc:
          batch_size: 50
        default_batch_fetch_size: 50

或者使用您的附加查询获取成员列表,并以这种方式将其合并到 Mapstruct 中(我认为这是一个更糟糕的选择):

  @Mapping(target = "members", source = "members")
  CasesDto toDto(CaseEntity entity, List<MemberEntity> members);

推荐阅读