Issue
I am writing an MVC
REST
application with Spring Boot
and Hibernate
. I decided to do DTO
mapping using MAPSTRUCT
. It seems that I did everything according to the guide, but an error is issued. What is the problem, I cannot understand. There is very little information on forums and on google.
P.S. At first I thought that the problem was in Lombok
, so I removed Lombok
and manually assigned getters / setters
. Then the problem was not solved. I took both in the Drink
class and in the DrinkDTO
I prescribed getters / setters
. It still didn't help.
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);
}
Solution
The error comes from the fact that you tried to map properties from List<>
objects, but those don't exist. Mapstruct is smart enough to generate mappers between lists, provided it knows how to map the elements inside the list.
So you don't need to specify @Mapping
annotations on the list-to-list mapping. Mapstruct will use the drinkToDrinkDTO
mapping method automatically.
@Mapping(...)
DrinkDTO drinkToDrinkDTO(Drink drink);
List<DrinkDTO> drinksToDrinksDTO(List<Drink> drinks);
Answered By - GeertPt
Answer Checked By - David Goodson (JavaFixing Volunteer)