MapStruct Impl ne génère pas le bon mappage

Nov 09 2020

Le mappage qualifiéByName ne génère pas le bon fichier impl.

Code:

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

Code généré:

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

Si je vérifie le code généré, le createdDate et lastModifiedDate n'utilisent pas la méthode DateFormatConversion.class withDateFormatConversion.

Mais il a défini la dernière date modifiée avec un format de date simple comme

hospitalDetails.setLastModifiedDate( new SimpleDateFormat().parse( hospitalDetailsDTO.getLastModifiedDate() ) );

pourquoi le fichier généré impl ne choisit pas DateFormatConversion.class pour mapper le createdDate et le lastModifiedDate?

Réponses

ElmarBrauch Nov 16 2020 at 16:58

Le JavaDoc de type Annotation Mapper dit à propos de l'attribut "uses":

Autres types de mappeur utilisés par ce mappeur. Il peut s'agir de classes manuscrites ou d'autres mappeurs générés par MapStruct.

Votre Bean "DateFormatConversion" peut ne pas être identifié comme une classe de mappage manuscrite.
Vous pouvez également créer une interface annotée @Mapper DateFormatConversion et fournir une méthode par défaut avec le même code que dans votre méthode withDateFormatConversion.