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

标签 java mapstruct

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

如果我创建新实体,但在添加新子实体之前无法清除更新时的子实体,则效果很好。

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 有一个带有测试用例的完整示例来重现问题。

以下是类(class):

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 子女与 parent 的关系如何?

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

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

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

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

关于java - Mapstruct:使用加法器时清除更新集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54881461/

相关文章:

java - 将大型方法分解为较小的方法时,适当的访问级别实践?

java - Mapstruct 自定义映射器并自动生成一个

java - 具有完全相同字段的对象之间的映射结构

java - MapStruct 按原样映射嵌套 bean

java - 如何正确使用MapStruct @Mapping和@Mappings?

Java 类型-细化映射

java - 开头包含 '[' 的字符串匹配错误

java - 自定义 spring-data 存储库后端

java - 复制 Intent/更改源 Activity 和目标类

java - Mockito @InjectMocks 未将 @Spy 分配给正确的字段