I wonder if it is possible to apply a conditional expression when converting an entity to dto using mapstruct. There are many search results for property, but I can't find it when I'm curious.
In the example code below, in the StudentMenuMapperImpl.java
file
list.add( toDto( studentMenu ) )
I want to give conditional expression to
I know how to override toDto in StudentMenuMapper
Interface.
But I want to know another simple way. (like annotation)
Alternatively, is it possible to return null from the toDto function with @AfterMapping
and @BeforeMapping
?
[StudentMenuDto.java]
public class StudentMenuDto {
private Long id;
private Long parentId;
List<StudentMenuDto> childStudentMenuList;
}
[GenericMapper.java]
public interface GenericMapper<D, E> {
D toDto(E entity);
List<D> toDto(List<E> entityList);
}
[StudentMenuMapper.java]
@Mapper
public interface StudentMenuMapper extends GenericMapper<StudentMenuDto, StudentMenu> {
StudentMenuMapper INSTANCE = Mappers.getMapper(StudentMenuMapper.class);
@Override
StudentMenuDto toDto(StudentMenu entity);
}
[StudentMenuMapperImpl.java] - impl file genereated by mapstruct
@Component
public class StudentMenuMapperImpl implements StudentMenuMapper {
@Override
public List<StudentMenuDto> toDto(List<StudentMenu> entityList) {
if ( entityList == null ) {
return null;
}
List<StudentMenuDto> list = new ArrayList<StudentMenuDto>( entityList.size() );
for ( StudentMenu studentMenu : entityList ) {
/* [AS-IS] */
list.add( toDto( studentMenu ) );
/* [TO-BE] I want to add various conditional statements like this
if(studentMenu.getId != 1){
list.add( toDto( studentMenu ) );
}
*/
}
return list;
}
@Override
public StudentMenuDto toDto(StudentMenu entity) {
if ( entity == null ) {
return null;
}
StudentMenuDto studentMenuDto = new StudentMenuDto();
studentMenuDto.setId( entity.getId() );
studentMenuDto.setParentId( entityParentStudentMenuId( entity ) );
studentMenuDto.setChildStudentMenuList( toDto( entity.getChildStudentMenuList() ) );
return studentMenuDto;
}
private Long entityParentStudentMenuId(StudentMenu studentMenu) {
if ( studentMenu == null ) {
return null;
}
StudentMenu parentStudentMenu = studentMenu.getParentStudentMenu();
if ( parentStudentMenu == null ) {
return null;
}
Long id = parentStudentMenu.getId();
if ( id == null ) {
return null;
}
return id;
}
}
They are working on this type of filter, which will be released with version 1.6.0
You can follow the request on github: Allow conditions/filters mapping iterables and maps
At the moment the solution is to create a method annoted with @AfterMapping which simply remove useless object from the list.
@AfterMapping
default void removeNullItem(
@MappingTarget List<Target> listTarget
) {
listTarget.removeIf(Objects::isNull);
}
If you need, you can take a look to: After-Mapping Annotations