当前位置: 首页 > 知识库问答 >
问题:

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

龙永逸
2023-03-14

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

如果我创建了新实体,但在添加新子实体之前,无法在更新时清除子实体,则此操作可以正常工作。

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个答案

令狐嘉禧
2023-03-14

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

考虑这一点(当思考MapStruct应该做什么来更新集合):

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

关于后一种方法,Dali(Eclipse)还生成remove方法。那么MapStruct应该根据上述情况调用这些吗?

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

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

如果你想要一个处理孩子/父母关系的好方法,并将其与JPA整合。。看看这些例子。

 类似资料:
  • 问题内容: 我尝试将DTO对象映射到我的JPA实体。我有一个集合在我的。可以添加它们。Mapstruct通过(http://mapstruct.org/documentation/dev/reference/html/#collection- mapping- strategies )支持使用加法器。 如果创建新实体,此方法效果很好,但是在添加新子代之前,在更新时无法清除子代。 Mapstruct

  • 问题内容: 我发现从Hibernate的集合中删除orphan记录并没有被删除。我一定在做一些简单的错误(这是Hibernate-101!),但是我找不到它。 给定以下内容: 以及以下更新代码: DAO片段: 以下测试失败: 总而言之,我发现: 从作者的藏书中删除该书后,该书仍存在于数据库中 如果我检查,那本书不存在该书 这种“感觉”就像我没有刷新会话或适当地强制进行更新-但我不确定应该在哪里进行

  • 在没有接口构建器的情况下创建视图方面,我是新手。我正在使用创建视图! 如何在重用约束之前删除它?

  • 问题内容: 我有一个对象,该对象有几个用public getter但私有setter定义的集合属性,在这种情况下,将反序列化的项目添加到这些集合中,而现有的项目保持不变。 在反序列化之前清除此类成员集合时,我需要采取一种行为。 我尝试使用带有属性的方法手动清除集合。 这种方法的问题在于,即使在JSON字符串中不存在collection属性,它仍将清除集合。 当仅清除那些在JSON字符串中实际定义的

  • 问题内容: 我在这段代码上遇到了麻烦。 我正在使用一个随机数启动一个计时器,并且我想每秒倒数一次更新JLabel。但是我还没有弄清楚该怎么做,因为计时器触发的唯一侦听器位于它的末尾(我知道)。 这是代码: 问题答案: 我不太了解您为什么使用随机数的问题,但以下是一些观察结果: 我想每秒钟更新一次带有倒计时的JLabel。 然后,您需要将计时器设置为每秒触发一次。因此,计时器的参数是1000,而不是

  • 我正在使用MapStruct从一个JPA实体映射到一个POJO DTO,在一个带有依赖项注入的Spring应用程序中。 ...并且从不为集合中的项调用修饰方法。 有没有一种方法可以让Mapstruct在集合映射中使用decorator方法,而不是在我的decorator中手动编写集合方法(这种方法很有效,但很冗长,并且违背了Mapstruct最初的目的,即不必编写这种代码)?