Mapstruct: Clear Collection on update when using Adders

痴心易碎 提交于 2019-12-20 04:31:09

问题


I try to map my DTO objects to my JPA entities. I have a Collection of children in my ParentEntity. They can be added addChild(). Using the Adder is supported by Mapstruct via the CollectionMappingStrategy (http://mapstruct.org/documentation/dev/reference/html/#collection-mapping-strategies).

This works fine if I create new entities, but fails to clear the children on updating before adding the new children.

The Mapstruct manual says (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.

What am I missing? Is there an additional option I have to set? There is a full example with test case to reproduce the problem at https://github.com/davidfuhr/mapstruct-jpa-child-parent

Here are the classes:

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:


The text in the documentation need to be rephrased. The problem is that especially for collections, there's no good way to handle this out of the box in MapStruct. I'm currently writing some new text for the documentation.

Consider this (when thinking what MapStruct should do for updating collections in general):

  • What if there's no match: should the non-matching elements be removed?
  • Should the non matching source elements be added?
  • What exactly constitutes to a match: equals? hashcode? comparator==0?
  • Can there be more than one match (Lists, but also depending on what is considered a match.)
  • How should the resulting collection be sorted?
  • Should a newly created object be added to a persistence context?
  • What about JPA child-parent relations?

About the latter one, Dali (Eclipse) also generates remove methods. So should MapStruct call these in the light of the above?

At this moment it works like this: whenever the user wants a collection update method, MapStruct generates a regular call to element mappings (in stead of an update call), because it is the only sensible thing to do. All the remainder is highly dependent on the use-case. If you need to clear the collection at before hand, use the @BeforeMapping to clear it.

Note: I just fixed an issue that handles also adders in this fashion in stead of the vague error message you get now.

If you want a nice way to handle child/parent relations and integrate them with JPA.. have a look at the examples.



来源:https://stackoverflow.com/questions/54881461/mapstruct-clear-collection-on-update-when-using-adders

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!