TransWikia.com

@MAPSTRUCT. No property named "packaging" exists in source parameter(s)

Stack Overflow на русском Asked by Artur Vartanyan on November 24, 2021

Я пишу MVC Rest-приложение. Использую Spring и Hibernate. Решил делать маппинг в DTO через Mapstruct. Кажется, я все делал по инструкции, но выдается ошибка. В чем проблема, я не могу понять. На форумах и в гугле очень мало информации.

P.S. Я не использую в данном случае Ломбок. Геттеры и Сеттеры прописаны вручную.

Drink:

@Entity
@Table(name = "drink", schema = "public")
public class Drink {

    public Drink() { // Constructor for Hibernate

    }


    // Fields
    //
    private @Id
    @GeneratedValue
    Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "price")
    private float price;

    @Column(name = "about")
    private String about;

    @Column(name = "is_deleted")
    private boolean isDeleted;

    // Relationships
    //
    @ManyToOne
    @JoinColumn(name = "packaging_id")
    private Packaging packaging;

    @ManyToOne
    @JoinColumn(name = "manufacturer_id")
    private Manufacturer manufacturer;

    @ManyToOne
    @JoinColumn(name = "country_id")
    private Countries countries;
}

DrinkDTO:

public class DrinkDTO {

    // Fields
    //
    private String drinkName;

    private float drinkPrice;

    private String drinkAbout;

    private Packaging drinkPackaging;

    private Manufacturer drinkManufacturer;

    private Countries drinkCountries;


    // Getters and Setters
    //
    public String getDrinkName() {
        return drinkName;
    }

    public void setDrinkName(String drinkName) {
        this.drinkName = drinkName;
    }

    public float getDrinkPrice() {
        return drinkPrice;
    }

    public void setDrinkPrice(float drinkPrice) {
        this.drinkPrice = drinkPrice;
    }

    public String getDrinkAbout() {
        return drinkAbout;
    }

    public void setDrinkAbout(String drinkAbout) {
        this.drinkAbout = drinkAbout;
    }

    public Packaging getDrinkPackaging() {
        return drinkPackaging;
    }

    public void setDrinkPackaging(Packaging drinkPackaging) {
        this.drinkPackaging = drinkPackaging;
    }

    public Manufacturer getDrinkManufacturer() {
        return drinkManufacturer;
    }

    public void setDrinkManufacturer(Manufacturer drinkManufacturer) {
        this.drinkManufacturer = drinkManufacturer;
    }

    public Countries getDrinkCountries() {
        return drinkCountries;
    }

    public void setDrinkCountries(Countries drinkCountries) {
        this.drinkCountries = drinkCountries;
    }

    // toSTRING
    @Override
    public String toString() {
        return "DrinkDTO{" +
                "drinkName='" + drinkName + ''' +
                ", drinkPrice=" + drinkPrice +
                ", drinkAbout='" + drinkAbout + ''' +
                ", drinkPackaging=" + drinkPackaging +
                ", drinkManufacturer=" + drinkManufacturer +
                ", drinkCountries=" + drinkCountries +
                '}';
    }

CustomerController:

@GetMapping("/drinks")
    List<DrinkDTO> getAllDrinks(){
        return DrinkMapper.INSTANCE.drinksToDrinksDTO(customerService.getAllDrinks());
    }

BUILD.GRADLE

// Mapstruct
    implementation 'org.mapstruct:mapstruct:1.3.1.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.3.1.Final'

DrinkMapper:

@Mapper
public interface DrinkMapper {

    DrinkMapper INSTANCE = Mappers.getMapper(DrinkMapper.class);

    @Mapping(source = "name", target = "drinkName")
    @Mapping(source = "price", target = "drinkPrice")
    @Mapping(source = "about", target = "drinkAbout")
    @Mapping(source = "packaging", target = "drinkPackaging")
    @Mapping(source = "manufacturer", target = "drinkManufacturer")
    @Mapping(source = "countries", target = "drinkCountries")
    DrinkDTO drinkToDrinkDTO(Drink drink);

    @Mapping(source = "drinkName", target = "name")
    @Mapping(source = "drinkPrice", target = "price")
    @Mapping(source = "drinkAbout", target = "about")
    @Mapping(source = "drinkPackaging", target = "packaging")
    @Mapping(source = "manufacturer", target = "drinkManufacturer")
    @Mapping(source = "countries", target = "drinkCountries")
    Drink drinkDTOtoDrink(DrinkDTO drinkDTO);

    @Mapping(source = "name", target = "drinkName")
    @Mapping(source = "price", target = "drinkPrice")
    @Mapping(source = "about", target = "drinkAbout")
    @Mapping(source = "packaging", target = "drinkPackaging")
    @Mapping(source = "manufacturer", target = "drinkManufacturer")
    @Mapping(source = "countries", target = "drinkCountries")
    List<DrinkDTO> drinksToDrinksDTO(List<Drink> drinks);
}

ERRORS:
enter image description here

One Answer

  1. Для маппинга drinkDTOtoDrink необходимо поменять местами manufacturer и drinkManufacturer, countries и drinkCountries.
  2. Для маппинга drinksToDrinksDTO не нужно перечислять маппинг полей. Вместо этого необходимо указать какой маппинг нужно использовать. В данном случае drinkToDrinkDTO.
  3. Для маппинга drinkDTOtoDrink добавить игнорирование полей id и deleted

Вот исправленный код:

import org.mapstruct.*;
import org.mapstruct.factory.Mappers;

import java.util.List;

@Mapper
public interface DrinkMapper {

    DrinkMapper INSTANCE = Mappers.getMapper(DrinkMapper.class);

    @Named("drinkToDrinkDTO")
    @Mappings({
            @Mapping(source = "name", target = "drinkName"),
            @Mapping(source = "price", target = "drinkPrice"),
            @Mapping(source = "about", target = "drinkAbout"),
            @Mapping(source = "packaging", target = "drinkPackaging"),
            @Mapping(source = "manufacturer", target = "drinkManufacturer"),
            @Mapping(source = "countries", target = "drinkCountries")
    })
    DrinkDTO drinkToDrinkDTO(Drink drink);

    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(target = "deleted", ignore = true),
            @Mapping(source = "drinkName", target = "name"),
            @Mapping(source = "drinkPrice", target = "price"),
            @Mapping(source = "drinkAbout", target = "about"),
            @Mapping(source = "drinkPackaging", target = "packaging"),
            @Mapping(source = "drinkManufacturer", target = "manufacturer"),
            @Mapping(source = "drinkCountries", target = "countries")
    })
    Drink drinkDTOtoDrink(DrinkDTO drinkDTO);

    @IterableMapping(qualifiedByName = "drinkToDrinkDTO")
    List<DrinkDTO> drinksToDrinksDTO(List<Drink> drinks);

}

Код небольшого теста:

import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class DrinkMapperTest {

    @Test
    void dto2entity() {
        DrinkDTO dto = new DrinkDTO();
        dto.setDrinkName("test");

        Drink entity =
                DrinkMapper.INSTANCE.drinkDTOtoDrink(dto);
        assertThat(entity).isNotNull();
        assertThat(entity.getName()).isEqualTo(dto.getDrinkName());
    }

    @Test
    void entity2dto() {
        Drink entity = new Drink();
        entity.setName("test");

        DrinkDTO dto =
                DrinkMapper.INSTANCE.drinkToDrinkDTO(entity);
        assertThat(dto).isNotNull();
        assertThat(dto.getDrinkName()).isEqualTo(entity.getName());
    }

    @Test
    void entityList2dtoList() {
        Drink entity = new Drink();
        entity.setName("test");

        List<Drink> entityList =
                Collections.singletonList(entity);

        List<DrinkDTO> dtoList =
                DrinkMapper.INSTANCE.drinksToDrinksDTO(
                        entityList);
        assertThat(dtoList).isNotNull();
        assertThat(dtoList).hasSize(1);
        assertThat(dtoList.get(0)).isNotNull();
        assertThat(dtoList.get(0).getDrinkName()).isEqualTo(entity.getName());
    }

}

Answered by Alexandr on November 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP