【问题标题】:MapStruct One to Many Relationship is not generated未生成 MapStruct 一对多关系
【发布时间】:2020-07-29 06:28:51
【问题描述】:

我想要一个简单的父子关系,但不知何故它不起作用,我不明白缺少的东西。

父映射器接口(添加uses = {LayerMapper.class} 不会改变任何东西):

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
@DecoratedWith(MlpConfigMapperDecorator.class)
public interface MlpConfigMapper {

    @Mapping(target = "epochNumber", source = "epochs")
    @Mapping(target = "activationFunction", ignore = true)
    MlpConfig toEntity(CustomMlpConfigRequest mlpConfigDto);
}

根据这个答案的父装饰器(https://stackoverflow.com/a/60217018/10565504):

public abstract class MlpConfigMapperDecorator implements MlpConfigMapper {

    @Autowired
    @Qualifier("delegate")
    private MlpConfigMapper delegate;

    @Autowired
    private ActivationFunctionService activationFunctionService;

    @Override
    public MlpConfig toEntity(CustomMlpConfigRequest mlpConfigDto) {

        MlpConfig mlpConfig = delegate.toEntity(mlpConfigDto);

        mlpConfig.setActivationFunction(activationFunctionService.findByType(mlpConfigDto.getActivationFunction()));

        return mlpConfig;
    }
}

父级 DTO:

public class CustomMlpConfigRequest {

    private String name;

    private String description;

    private int batchSize;

    private int epochs;

    private List<LayerDto> layers;

    private String activationFunction;

}

子 DTO:

public class LayerDto {

    public String type;
    public int orderNumber;
    public int neuronsNumber;

}

父实体:

public class MlpConfig {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String name;

    private String description;

    private int batchSize;

    private int epochNumber;

    @JoinColumn(nullable = false, name = "activationFunction_id")
    @ManyToOne(fetch = FetchType.LAZY)
    private ActivationFunction activationFunction;

    @JsonManagedReference
    @Column(nullable = false)
    @OneToMany(mappedBy = "mlpConfig", cascade = CascadeType.ALL)
    private List<Layer> layers;

    @ManyToOne(fetch = FetchType.LAZY)
    private User user;

    private Date lastUpdated;
}

子实体:

public class Layer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private ELayer type;

    private int neuronsNumber;

    private int orderNumber;

    @EqualsAndHashCode.Exclude
    @ToString.Exclude
    @ManyToOne(fetch = FetchType.LAZY, optional=false)
    @JoinColumn(name = "mlpConfig_id", nullable=false)
    @JsonBackReference
    private MlpConfig mlpConfig;
}

生成的子实体映射器方法(在我的情况下缺少 setChildren 或 setMlpConfig()):

@Override
public LayerDto layerToDto(Layer layer) {
    if ( layer == null ) {
        return null;
    }

    LayerDto layerDto = new LayerDto();

    if ( layer.getType() != null ) {
        layerDto.setType( layer.getType().name() );
    }
    layerDto.setOrderNumber( layer.getOrderNumber() );
    layerDto.setNeuronsNumber( layer.getNeuronsNumber() );

    return layerDto;
}

如何让映射器在孩子中设置父级?

【问题讨论】:

    标签: java mapstruct


    【解决方案1】:

    你有Layer toEntity(LayerDto layerDto);

    另外,在实体类的层设置器上,你应该说,layers.forEach (layer -&gt; layer.setmlpConfig(this));

    你做了那个设置工作吗?如果你不这样做,当你尝试获取它时,mplConfig 实体的层总是可以为空。

    【讨论】:

    • 是的,抱歉,我有 toEntity 方法。为什么每个?我正在使用 lombok 作为 getter 和 setter,所以一切都应该没问题。在图层实体侧存在以下内容:public void setMlpConfig(MlpConfig mlpConfig) { this.mlpConfig = mlpConfig; }
    • 我认为问题是在LayerDTO中不存在与MlpConfigCustomMlpConfigRequest的对应关系。
    • 我认为你应该重写层的设置器。由于 LayerDto(当然)没有 MlpConfig,它的 MlpConfig 始终为 null 。所以在层的设置器上,如果你说这个“layers.forEach (layer -> layer.setmlpConfig(this));”,我认为他们的 MlpConfig 不会再次为空
    • 在哪个实体中?为什么?我还是没明白重点。问题出在哪里?
    • 我不确定这是否是您的问题,但我曾经遇到过同样的问题,这就是我的答案。你能试试吗?
    【解决方案2】:

    最后我自己修好了。我不知道这是否是最佳实践,并且映射器可能应该在没有手动帮助的情况下进行,但至少它可以工作:

    public abstract class MlpConfigMapperDecorator implements MlpConfigMapper {
    
        @Autowired
        @Qualifier("delegate")
        private MlpConfigMapper delegate;
    
        @Autowired
        private ActivationFunctionService activationFunctionService;
    
        @Override
        public MlpConfig mlpConfigToEntity(CustomMlpConfigRequest mlpConfigDto) {
    
            MlpConfig mlpConfig = delegate.mlpConfigToEntity(mlpConfigDto);
    
            mlpConfig.setActivationFunction(activationFunctionService.findByType(mlpConfigDto.getActivationFunction()));
            
            //this is the difference. I set the config for the layer manually
            mlpConfig.getLayers().forEach(e -> e.setMlpConfig(mlpConfig));
    
            return mlpConfig;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-03
      • 2011-08-27
      • 2022-01-08
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 2018-08-11
      相关资源
      最近更新 更多