Mapstruct: очистить коллекцию при обновлении при использовании Adders - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь сопоставить свои объекты DTO с сущностями JPA.У меня есть коллекция children в моем ParentEntity.Их можно добавить addChild().Использование Adder поддерживается Mapstruct через CollectionMappingStrategy (http://mapstruct.org/documentation/dev/reference/html/#collection-mapping-strategies).

. Это прекрасно работает, если я создаю новые объекты, но не может очистить дочерние элементы при обновлении перед добавлением новых дочерних элементов.

В руководстве Mapstruct сказано, что (http://mapstruct.org/documentation/dev/reference/html/#updating-bean-instances):

Свойства набора или карты целевого компонента, подлежащего обновлению, будут очищены, а затем заполнены значениями из соответствующей исходной коллекции или карты.

Чего мне не хватает? Есть ли дополнительная опция, которую я должен установить? Есть полный пример с контрольным примером для воспроизведения проблемы на 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 Ответ

0 голосов
/ 26 февраля 2019

Текст в документации необходимо перефразировать.Проблема в том, что, особенно для коллекций, в MapStruct нет хорошего способа справиться с этим.В настоящее время я пишу новый текст для документации.

Учтите это (подумав, что MapStruct должен сделать для обновления коллекций в целом):

  • Что если совпадений нет: следует удалить несоответствующие элементы?
  • Должны ли быть добавлены несовпадающие исходные элементы?
  • Что именно соответствует совпадению: равно?хэш-код?компаратор == 0?
  • Может ли быть несколько совпадений (списки, но также и в зависимости от того, что считается совпадением.)
  • Как сортировать итоговую коллекцию?
  • Должен ли вновь созданный объект быть добавлен в контекст постоянства?
  • А как насчет дочерних и родительских отношений JPA?

Что касается последнего, Дали (Eclipse) также генерирует методы удаления,Так должен ли MapStruct вызывать их в свете вышесказанного?

В данный момент это работает следующим образом: всякий раз, когда пользователь хочет получить метод обновления коллекции, MapStruct генерирует регулярный вызов сопоставлений элементов (вместо вызова обновления).), потому что это единственная разумная вещь, которую нужно сделать.Все остальное сильно зависит от варианта использования.Если вам нужно очистить коллекцию заранее, используйте @BeforeMapping, чтобы очистить ее.

Примечание: я только что исправил проблему, которая обрабатывает также сумматоры таким образом вместо смутного сообщения об ошибке, которое вы получаете сейчас.

Если вы хотите получить хороший способ обработки дочерних / родительских отношений и интеграции их с JPA ... взгляните на examples .

...