MapStruct Impl не генерирует правильное отображение
Отображение qualByName не создает правильный файл impl.
Код:
HospitalMapper.java
package com.company.tracker.hospitals.vo.mapper;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import com.company.tracker.hospitals.entity.HospitalDetails;
import com.company.tracker.hospitals.vo.HospitalDetailsDTO;
@Mapper(componentModel = "spring", uses = {DateFormatConversion.class,ObjectAfterMapping.class }, config = AuditMapper.class)
public interface HospitalDetailsMapper {
@Mappings({
@Mapping(source = "creationDate", target = "creationDate", qualifiedByName = "withDateFormatConversion"),
@Mapping(source = "lastModifiedDate", target = "lastModifiedDate", qualifiedByName = "withDateFormatConversion") })
HospitalDetails hospitalDetailsDTOToHospitalDetails(HospitalDetailsDTO hospitalDetailsDTO);
@Mappings({
@Mapping(source = "creationDate", target = "creationDate", qualifiedByName = "StringToDateFormat"),
@Mapping(source = "lastModifiedDate", target = "lastModifiedDate", qualifiedByName = "StringToDateFormat") })
HospitalDetailsDTO hospitalDetailsToHospitalDetailsDTO(HospitalDetails hospitalDetails);
List<HospitalDetailsDTO> hospitalDetailsToHospitalDetailsDTO(List<HospitalDetails> hospitalDetails);
List<HospitalDetails> hospitalDetailsDTOToHospitalDetails(List<HospitalDetails> hospitalDetailsDTO);
@Named("withDateFormatConversion")
default LocalDate withDateFormatConversion(String date) throws ParseException {
ZoneId defaultZoneId = ZoneId.systemDefault();
System.out.println("System Default TimeZone : " + defaultZoneId);
Date date1=new SimpleDateFormat("dd-MM-yyyy").parse(date);
//1. Convert Date -> Instant
Instant instant = date1.toInstant();
//2. Instant + system default time zone + toLocalDate() = LocalDate
return instant.atZone(defaultZoneId).toLocalDate();
}
}
DateFormatConversion.java:
package com.company.tracker.hospitals.vo.mapper;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import org.mapstruct.Named;
import org.springframework.stereotype.Component;
@Component
public class DateFormatConversion {
@Named("withDateFormatConversion")
public LocalDate withDateFormatConversion(String date) throws ParseException {
ZoneId defaultZoneId = ZoneId.systemDefault();
System.out.println("System Default TimeZone : " + defaultZoneId);
Date date1=new SimpleDateFormat("dd-MM-yyyy").parse(date);
//1. Convert Date -> Instant
Instant instant = date1.toInstant();
//2. Instant + system default time zone + toLocalDate() = LocalDate
return instant.atZone(defaultZoneId).toLocalDate();
}
}
Сгенерированный код:
package com.company.tracker.hospitals.vo.mapper;
import com.company.tracker.hospitals.entity.HospitalDetails;
import com.company.tracker.hospitals.vo.HospitalDetailsDTO;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2020-11-09T17:22:28+0530",
comments = "version: 1.3.0.Final, compiler: Eclipse JDT (IDE) 3.21.0.v20200304-1404, environment: Java 1.8.0_261 (Oracle Corporation)"
)
@Component
public class HospitalDetailsMapperImpl implements HospitalDetailsMapper {
@Autowired
private ObjectAfterMapping objectAfterMapping;
@Override
public HospitalDetails hospitalDetailsDTOToHospitalDetails(HospitalDetailsDTO hospitalDetailsDTO) {
if ( hospitalDetailsDTO == null ) {
return null;
}
HospitalDetails hospitalDetails = new HospitalDetails();
try {
if ( hospitalDetailsDTO.getCreationDate() != null ) {
hospitalDetails.setCreationDate( new SimpleDateFormat().parse( hospitalDetailsDTO.getCreationDate() ) );
}
}
catch ( ParseException e ) {
throw new RuntimeException( e );
}
try {
if ( hospitalDetailsDTO.getLastModifiedDate() != null ) {
hospitalDetails.setLastModifiedDate( new SimpleDateFormat().parse( hospitalDetailsDTO.getLastModifiedDate() ) );
}
}
catch ( ParseException e ) {
throw new RuntimeException( e );
}
hospitalDetails.setCreatedBy( hospitalDetailsDTO.getCreatedBy() );
hospitalDetails.setIsDeleted( hospitalDetailsDTO.getIsDeleted() );
hospitalDetails.setLastModifiedBy( hospitalDetailsDTO.getLastModifiedBy() );
hospitalDetails.setAddress1( hospitalDetailsDTO.getAddress1() );
hospitalDetails.setAddress2( hospitalDetailsDTO.getAddress2() );
hospitalDetails.setAddress3( hospitalDetailsDTO.getAddress3() );
hospitalDetails.setCity( hospitalDetailsDTO.getCity() );
hospitalDetails.setDistrict( hospitalDetailsDTO.getDistrict() );
hospitalDetails.setHospitalId( hospitalDetailsDTO.getHospitalId() );
hospitalDetails.setHospitalName( hospitalDetailsDTO.getHospitalName() );
hospitalDetails.setLandmark( hospitalDetailsDTO.getLandmark() );
hospitalDetails.setRegistrationId( hospitalDetailsDTO.getRegistrationId() );
hospitalDetails.setStreetName( hospitalDetailsDTO.getStreetName() );
return hospitalDetails;
}
@Override
public HospitalDetailsDTO hospitalDetailsToHospitalDetailsDTO(HospitalDetails hospitalDetails) {
if ( hospitalDetails == null ) {
return null;
}
HospitalDetailsDTO hospitalDetailsDTO = new HospitalDetailsDTO();
if ( hospitalDetails.getCreationDate() != null ) {
hospitalDetailsDTO.setCreationDate( new SimpleDateFormat().format( hospitalDetails.getCreationDate() ) );
}
if ( hospitalDetails.getLastModifiedDate() != null ) {
hospitalDetailsDTO.setLastModifiedDate( new SimpleDateFormat().format( hospitalDetails.getLastModifiedDate() ) );
}
hospitalDetailsDTO.setCreatedBy( hospitalDetails.getCreatedBy() );
hospitalDetailsDTO.setIsDeleted( hospitalDetails.getIsDeleted() );
hospitalDetailsDTO.setLastModifiedBy( hospitalDetails.getLastModifiedBy() );
hospitalDetailsDTO.setAddress1( hospitalDetails.getAddress1() );
hospitalDetailsDTO.setAddress2( hospitalDetails.getAddress2() );
hospitalDetailsDTO.setAddress3( hospitalDetails.getAddress3() );
hospitalDetailsDTO.setCity( hospitalDetails.getCity() );
hospitalDetailsDTO.setDistrict( hospitalDetails.getDistrict() );
hospitalDetailsDTO.setHospitalId( hospitalDetails.getHospitalId() );
hospitalDetailsDTO.setHospitalName( hospitalDetails.getHospitalName() );
hospitalDetailsDTO.setLandmark( hospitalDetails.getLandmark() );
hospitalDetailsDTO.setRegistrationId( hospitalDetails.getRegistrationId() );
hospitalDetailsDTO.setStreetName( hospitalDetails.getStreetName() );
HospitalDetailsDTO target = objectAfterMapping.test( hospitalDetails, hospitalDetailsDTO );
if ( target != null ) {
return target;
}
return hospitalDetailsDTO;
}
@Override
public List<HospitalDetailsDTO> hospitalDetailsToHospitalDetailsDTO(List<HospitalDetails> hospitalDetails) {
if ( hospitalDetails == null ) {
return null;
}
List<HospitalDetailsDTO> list = new ArrayList<HospitalDetailsDTO>( hospitalDetails.size() );
for ( HospitalDetails hospitalDetails1 : hospitalDetails ) {
list.add( hospitalDetailsToHospitalDetailsDTO( hospitalDetails1 ) );
}
return list;
}
@Override
public List<HospitalDetails> hospitalDetailsDTOToHospitalDetails(List<HospitalDetails> hospitalDetailsDTO) {
if ( hospitalDetailsDTO == null ) {
return null;
}
List<HospitalDetails> list = new ArrayList<HospitalDetails>( hospitalDetailsDTO.size() );
for ( HospitalDetails hospitalDetails : hospitalDetailsDTO ) {
list.add( hospitalDetails );
}
return list;
}
}
Если я проверю сгенерированный код, createdDate и lastModifiedDate не используют метод DateFormatConversion.class withDateFormatConversion.
Но он установил дату последнего изменения с простым форматом даты как
hospitalDetails.setLastModifiedDate( new SimpleDateFormat().parse( hospitalDetailsDTO.getLastModifiedDate() ) );
почему сгенерированный файл impl не выбирает DateFormatConversion.class для сопоставления createdDate и lastModifiedDate?
Ответы
В JavaDoc типа Annotation Mapper говорится об атрибуте "использует":
Другие типы картографов, используемые этим картографом. Это могут быть рукописные классы или другие картографы, созданные MapStruct.
Ваш объект Bean «DateFormatConversion» не может быть идентифицирован как рукописный класс сопоставителя.
Вы также можете создать интерфейс DateFormatConversion с аннотациями @Mapper и предоставить метод по умолчанию с тем же кодом, что и в вашем методе withDateFormatConversion.