I have been working with MapStruct some days now and haven't yet achieved what i need.
As part of the exercises with Spring, I am writing a small app that will display information about the movies (title, description, director, etc.) and additionally the movie category. Therefore, I created an additional Entity called Category, so that (e.g. an admin) could add or remove individual category names.
Movie Entity:
public class Movie {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
private String director;
private int year;
@ManyToMany
@Column(nullable = false)
private List<Category> category;
private LocalDate createdAt;
}
Category Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String categoryName;
private LocalDate createdAt;
}
I packed it all into MapStruct and DTOs.
MovieDTORequest.java
public class MovieDTORequest {
private String title;
private String content;
private String director;
private List<Category> category;
private int year;
}
MovieDTOResponse.java
public class MovieDTOResponse {
private String title;
private String content;
private String director;
private String categoryName;
private int year;
private LocalDate createdAt;
}
And MovieMapper.java
@Mapper(componentModel = "spring")
public interface MovieMapper {
@Mapping(target = "categoryName", source = "category")
MovieDTOResponse movieToMovieDTO(Movie movie);
@Mapping(target = "id", source = "title")
@Mapping(target = "createdAt", constant = "")
Movie movieRequestToMovie(MovieDTORequest request);
@Mapping(target = "id", source = "title")
@Mapping(target = "createdAt", constant = "")
void updateMovie(MovieDTORequest request, @MappingTarget Movie target);
String map(List<Category> value);
}
However, I have a problem with Mapper. First, I got the error:
"Can't map property "List<Category> category" to "String categoryName". Consider to declare/implement a mapping method: "String map(List<Category> value)"
and when I wrote it in Mapper, I have one more error:
Can't generate mapping method from iterable type from java stdlib to non-iterable type.
I am asking for help, because I am already lost.
CodePudding user response:
You should define default implementation for String map(List<Category> value)
inside MovieMapper
interface, what would Mapstruct use to map property List<Category> category
to String categoryName
. For example:
@Mapper(componentModel = "spring")
public interface MovieMapper {
@Mapping(target = "categoryName", source = "category")
MovieDTOResponse movieToMovieDTO(Movie movie);
@Mapping(target = "id", source = "title")
@Mapping(target = "createdAt", constant = "")
Movie movieRequestToMovie(MovieDTORequest request);
@Mapping(target = "id", source = "title")
@Mapping(target = "createdAt", constant = "")
void updateMovie(MovieDTORequest request, @MappingTarget Movie target);
default String map(List<Category> value){
//TODO: Implement your own logic that determines categoryName
return "Movie Categories";
}
}