使用org.mapstruct框架进行一对多关系映射

问题描述

如何使用org.mapstruct框架将一对多关系映射?

DTO类:

componentDidMount() {
  getTime('Europe/London')
    .then((response) => this.setState({ london: response });
}

域类-

@Data
public class ScheduledJobDTO {

    private String jobName;
    private String jobGroup;
    private String jobClass;
    private String cronExpression;
    private Boolean cronJob;
    private Long repeatTime;
    private Integer repeatCount;
    private Set<ScheduledJobParamsDTO> paramtersDTOs;

}

@Data
@EqualsAndHashCode
public class ScheduledJobParamsDTO {

    String name;
    String value;
}

映射器类-

@Data
@Entity
@Table(name = "scheduled_job")
public class ScheduledJob {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "job_name")
    private String jobName;
    @Column(name = "job_group")
    private String jobGroup;
    @Column(name = "job_class")
    private String jobClass;
    @Column(name = "cron_expression")
    private String cronExpression;
    @Column(name = "is_cron_job")
    private Boolean cronJob;
    @Column(name = "repeat_time")
    private Long repeatTime;
    @Column(name = "repeat_count")
    private Integer repeatCount;
    @Column(name = "trigger_start_date")
    private LocalDate triggerStartDate;
    @Column(name = "trigger_end_date")
    private LocalDate triggerEndDate;
    @Column(name = "created_at")
    private LocalDate createdAt;
    @Column(name = "modified_at")
    private LocalDate modifiedAt;
    @Column(name = "is_active")
    private Boolean active;
    @OnetoMany(mappedBy = "scheduledJob")
    private Set<ScheduledJobParams> parameters;

}

@Data
@Entity
@Table(name = "scheduled_job_params")
@EqualsAndHashCode
public class ScheduledJobParams {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;
    @ManyToOne(fetch = FetchType.LAZY,optional = false)
    @JoinColumn(name = "scheduled_job_id",nullable = false)
    ScheduledJob scheduledJob;
    String name;
    String value;
}

现在,上面的映射器正在映射ScheduledJob和ScheduledJobParams,但是ScheduledJobParams引用了ScheduledJob。

如何将引用ScheduledJob映射到ScheduledJobParams?

解决方法

您可以通过@AfterMapping@MappedTarget来实现。参考文档12.2. Mapping customization with before-mapping and after-mapping methods中对此进行了说明。

// Java 8+ otherwise you need to use an abstract class and a for-loop instead
@Mapper(componentModel = "spring")
public interface ScheduledJobMapper {

    @Mapping(target = "parameters",source = "paramtersDTOs")
    ScheduledJob mapToDomain(ScheduledJobDTO dto);

    @AfterMapping
    default void after(@MappingTarget ScheduledJob domain,ScheduledJobDTO dto) {
        domain.getParameters().forEach(scheduledJobParams -> {
            scheduledJobParams.setScheduledJob(domain);
        });
    }
}

但是,我确定当您从 DTO 映射回实体时,您不需要填写双向关系(这就是您的理解)请参阅“域” )。请注意,如果处理不当,请打印出或序列化此类对象,即将其序列化为JSON或XML,并抛出java.lang.StackOverflowError