Mapstruct:使用加法器时在更新时清除集合

时间:2019-02-26 08:45:14

标签: java mapstruct

我尝试将DTO对象映射到我的JPA实体。我的children中有一个ParentEntity的集合。可以将它们添加addChild()。 Mapstruct通过CollectionMappingStrategyhttp://mapstruct.org/documentation/dev/reference/html/#collection-mapping-strategies)支持使用加法器。

如果我创建新实体,这很好用,但是在添加新子代之前,在更新时无法清除子代。

Mapstruct手册说(http://mapstruct.org/documentation/dev/reference/html/#updating-bean-instances):

  

将清除要更新的目标bean的集合或地图类型的属性,然后使用相应源集合或地图中的值填充。

我想念什么?我必须设置其他选项吗?在https://github.com/davidfuhr/mapstruct-jpa-child-parent

上有一个完整的测试案例示例,可以重现该问题。

以下是课程:

public class ParentEntity {

    private String name;
    private List<ChildEntity> children = new ArrayList<>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<ChildEntity> getChildren() {
        return children;
    }

    public void addChild(ChildEntity child) {
        children.add(child);
        child.setMyParent(this);
    }

    public void removeChild(ChildEntity child) {
        children.remove(child);
        child.setMyParent(null);
    }

}
public class ChildEntity {

    private String name;
    private ParentEntity myParent;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ParentEntity getMyParent() {
        return myParent;
    }

    public void setMyParent(ParentEntity myParent) {
        this.myParent = myParent;
    }

}
public class ParentDto {

   private String name;
   private List<ChildDto> children;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<ChildDto> getChildren() {
        return children;
    }

    public void setChildren(List<ChildDto> children) {
        this.children = children;
    }

}
public class ChildDto {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface SourceTargetMapper {

    SourceTargetMapper MAPPER = Mappers.getMapper(SourceTargetMapper.class);

    ParentEntity toEntity(ParentDto s);

    ParentEntity updateEntity(ParentDto s, @MappingTarget ParentEntity e);

    @Mapping(target = "myParent", ignore = true)
    ChildEntity toEntity(ChildDto s);
}

1 个答案:

答案 0 :(得分:3)

文档中的文字需要改写。问题在于,特别是对于集合而言,没有很好的方法在MapStruct中开箱即用地处理此问题。我目前正在为文档编写一些新文本。

考虑这一点(在考虑MapStruct一般应如何更新集合时):

  • 如果不匹配该怎么办:不匹配的元素应该删除吗?
  • 是否应添加不匹配的源元素?
  • 什么完全构成比赛:等于?哈希码?比较器== 0?
  • 是否可以有多个匹配项(列表,但还取决于被视为匹配项的内容。)
  • 应如何对所得集合进行排序?
  • 是否应将新创建的对象添加到持久性上下文?
  • JPA的亲子关系如何?

关于后一种方法,Dali(Eclipse)还生成remove方法。那么,MapStruct是否应该根据以上情况调用它们?

此时,它的工作方式是这样的:每当用户想要集合更新方法时,MapStruct都会生成对元素映射的常规调用(而不是更新调用),因为这是唯一明智的选择。所有其余部分高度依赖用例。如果您需要事先清除集合,请使用@BeforeMapping清除它。

注意:我只是解决了一个问题,该问题也可以用这种方式处理加法器,而不是现在得到的模糊错误消息。

如果您想要一种处理子/父关系并将其与JPA集成的好方法,请查看examples