Spring Boot @MAPSTRUCT,源参数中不存在名为“packaging”的属性

brgchamk  于 2023-05-17  发布在  Spring
关注(0)|答案(7)|浏览(214)

我正在用Spring BootHibernate编写一个MVCREST应用程序。我决定使用MAPSTRUCT进行DTOMap。似乎我按照指南做了一切,但发出了一个错误。有什么问题,我不明白。论坛和谷歌上的信息非常少。
P.S.一开始我以为问题出在Lombok上,所以我删除了Lombok并手动分配了getters / setters。那么问题就没有解决。我在Drink类和我指定的getters / setters中都取了值。但还是无济于事。
饮料:

@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 +
                '}';
    }

客户控制器:

@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);
}

错误:

pftdvrlh

pftdvrlh1#

对于那些在使用mapstruct + lombok时遇到相同问题的用户:
我也有同样的问题。原因是我也一直在使用Lombok插件。没有必要删除它,但你必须确保在pom.xml<annotationProcessorPaths> Lombok标记在Mapstruct标记之前。
示例(pom.xml文件的一部分):

<build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <source>${java.version}</source>
                        <target>${java.version}</target>
                        <encoding>${project.build.sourceEncoding}</encoding>
                        <annotationProcessorPaths>
                            <path>
                                <groupId>org.projectlombok</groupId> <!-- IMPORTANT - LOMBOK BEFORE MAPSTRUCT -->
                                <artifactId>lombok</artifactId>
                                <version>${lombok.version}</version>
                            </path>
                            <path>
                                <groupId>org.mapstruct</groupId>
                                <artifactId>mapstruct-processor</artifactId>
                                <version>${org.mapstruct.version}</version>
                            </path>
                        </annotationProcessorPaths>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
ozxc1zmp

ozxc1zmp2#

这个错误是因为您试图MapList<>对象的属性,但这些属性不存在。Mapstruct足够智能,可以在列表之间生成Map器,前提是它知道如何Map列表中的元素。
所以不需要在列表到列表Map中指定@Mapping注解。Mapstruct将自动使用drinkToDrinkDTOMap方法。

@Mapping(...)
DrinkDTO drinkToDrinkDTO(Drink drink);

List<DrinkDTO> drinksToDrinksDTO(List<Drink> drinks);
pprl5pva

pprl5pva3#

只是为了补充@Jakub Słowikowski的答案,Gradle依赖关系也会发生同样的情况。以下顺序导致错误:

dependencies {    
...
annotationProcessor("org.mapstruct:mapstruct-processor:${mapstructVersion}")

annotationProcessor("org.projectlombok:lombok:${lombokVersion}")
...
}

所以我不得不改变顺序:

dependencies {    
...
annotationProcessor("org.projectlombok:lombok:${lombokVersion}")
    
annotationProcessor("org.mapstruct:mapstruct-processor:${mapstructVersion}")
...
}
vzgqcmou

vzgqcmou4#

在我的例子中,错误不是源于annotationProcessors的声明顺序,而是源于缺少的Lombok注解。
我有一个CustomerCustomerDto的Map,但是Customer缺少getter和setter。

CustomerDto toCustomerDto(Customer customer);

@Data
public class CustomerDto {
  ...
}

public class Customer {
  ...
}

@Data添加到Customer类为我解决了这个问题。

izj3ouym

izj3ouym5#

如果您还有PackakingMapper、CoutriesMapper...,请尝试在@Mapper注解中添加uses参数。,就像这样:

@Mapper(uses = {PackagingMapper.class, CountriesMapper.class, ManufacturerMapper.class})
public interface DrinkMapper{
    ....
}
a14dhokn

a14dhokn6#

只需将lombok dependencie作为pom.xml文件中的第一个dependencie
然后重新加载maven项目

你不需要添加mapstruct插件,我只是使用了依赖

<dependencies>
    **<dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>**
    <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.5.5.Final</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.5.5.Final</version>
    </dependency>
    </dependencies>

    <build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludes>
                    <exclude>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

相信我****你仍然可以在你的项目中使用Lombok,即使你已经在Sping Boot Maven插件配置中排除了它。插件中的excludes配置只是告诉Maven从插件的类路径中排除指定的工件。在这种情况下,lombok工件将从Sping Boot Maven插件的类路径中排除,但不会从项目的类路径中排除。

mec1mxoz

mec1mxoz7#

步骤:
1.为DrinkDrinkDTO类生成Getters / Setters(可能没有Lombok)。
1.使用Gradle构建项目任务:Build
1.启动项目!

相关问题