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

Mapstruct: Clear Collection on update when using Adders

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

支持使用 Adder

如果我创建新实体,这会工作正常,但无法在添加新子项之前清除更新中的子项。

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

Collection- or map-typed properties of the target bean to be updated will be cleared and then populated with the values from the corresponding source collection or map.

我错过了什么?我必须设置其他选项吗?在 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);
}

文档中的文本需要重新措辞。问题是,特别是对于集合,在 MapStruct 中没有开箱即用的好方法来处理这个问题。我目前正在为文档编写一些新文本。

考虑这个(在思考 MapStruct 应该做什么来更新集合时):

  • 如果没有匹配怎么办:是否应该删除不匹配的元素?
  • 是否应添加不匹配的源元素?
  • 匹配的确切组成:等于?哈希码?比较器==0?
  • 是否可以有多个匹配项(列表,但也取决于什么被视为匹配项。)
  • 生成的集合应该如何排序?
  • 是否应该将新创建的对象添加到持久性上下文中?
  • JPA 父子关系如何?

关于后一种,大理(Eclipse)也生成了remove方法。那么 MapStruct 是否应该根据上述调用这些?

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

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

如果您想要一种很好的方式来处理 child/parent 关系并将它们与 JPA 集成.. 请查看 examples