Mapstruct:使用Adders时更新时清除收藏

问题描述 投票:1回答:1

我尝试将我的DTO对象映射到我的JPA实体。我在children收集了ParentEntity。他们可以添加addChild()。 Mapstruct通过CollectionMappingStrategyhttp://mapstruct.org/documentation/dev/reference/html/#collection-mapping-strategies)支持使用Adder。

如果我创建新实体,但在添加新子项之前无法清除更新子项,则此方法正常。

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);
}
java mapstruct
1个回答
3
投票

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

考虑一下(当考虑MapStruct应该如何更新集合时):

  • 如果没有匹配怎么办:是否应该删除不匹配的元素?
  • 是否应添加非匹配的源元素?
  • 究竟什么构成了一场比赛:等于?哈希码?比较== 0?
  • 可以有多个匹配(列表,但也取决于被认为匹配的内容。)
  • 如何对生成的集合进行排序?
  • 是否应将新创建的对象添加到持久性上下文中?
  • JPA的父母关系怎么样?

关于后者,Dali(Eclipse)也生成删除方法。那么MapStruct应该根据上述内容调用这些内容吗?

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

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

如果你想要一个很好的方法来处理子/父关系并将它们与JPA集成..看看examples

© www.soinside.com 2019 - 2024. All rights reserved.