Skip to content

Mapping control disabling conversions does not disable them in 2 step mappings #3186

@beifuyiqiedeqilin

Description

@beifuyiqiedeqilin

Use case

Source:

public class WatermarkAnalysisDTO {
    private java.util.Date uploadTime;
    public java.util.Date getUploadTime() {
        return uploadTime;
    }

    public void setUploadTime(java.util.Date uploadTime) {
        this.uploadTime = uploadTime;
    }
}

target:

public class WatermarkAnalysis {
    private String uploadTime;
    public String getUploadTime() {
        return uploadTime;
    }

    public void setUploadTime(String uploadTime) {
        this.uploadTime = uploadTime;
    }
}
@Retention(RetentionPolicy.CLASS)
@MappingControl(MappingControl.Use.DIRECT)
@MappingControl(MappingControl.Use.MAPPING_METHOD)
@MappingControl(MappingControl.Use.COMPLEX_MAPPING)
public @interface NoConversationMapping {
}

mapper:

@Mapper(mappingControl = NoConversationMapping.class)
public interface WatermarkAnalysisMapper {
    WatermarkAnalysisMapper MAPPER = Mappers.getMapper(WatermarkAnalysisMapper.class);
    WatermarkAnalysis convertDTO(WatermarkAnalysisDTO watermarkAnalysisDTO);
}

Generated Code

As #1428 mentioned, I expected target result is null. but MapStruct still do conversion for me

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-03-07T16:52:36+0800",
    comments = "version: 1.4.2.Final, compiler: javac, environment: Java 17.0.2 (Oracle Corporation)"
)
@Component
public class WatermarkAnalysisMapperImpl implements WatermarkAnalysisMapper {

    private final DatatypeFactory datatypeFactory;

    public WatermarkAnalysisMapperImpl() {
        try {
            datatypeFactory = DatatypeFactory.newInstance();
        }
        catch ( DatatypeConfigurationException ex ) {
            throw new RuntimeException( ex );
        }
    }

    @Override
    public WatermarkAnalysis convertDTO(WatermarkAnalysisDTO watermarkAnalysisDTO) {
        if ( watermarkAnalysisDTO == null ) {
            return null;
        }

        WatermarkAnalysis watermarkAnalysis = new WatermarkAnalysis();
        watermarkAnalysis.setUploadTime( xmlGregorianCalendarToString( dateToXmlGregorianCalendar( watermarkAnalysisDTO.getUploadTime() ), null ) );

        return watermarkAnalysis;
    }

    private String xmlGregorianCalendarToString( XMLGregorianCalendar xcal, String dateFormat ) {
        if ( xcal == null ) {
            return null;
        }

        if (dateFormat == null ) {
            return xcal.toString();
        }
        else {
            Date d = xcal.toGregorianCalendar().getTime();
            SimpleDateFormat sdf = new SimpleDateFormat( dateFormat );
            return sdf.format( d );
        }
    }

    private XMLGregorianCalendar dateToXmlGregorianCalendar( Date date ) {
        if ( date == null ) {
            return null;
        }

        GregorianCalendar c = new GregorianCalendar();
        c.setTime( date );
        return datatypeFactory.newXMLGregorianCalendar( c );
    }
}

Possible workarounds

We are doing switch cglib to mapstruct. As we have a lot of usage of bean copy, If we change history codes, we must do more test. So we expected the same behaviors with cglib. In above case, cglib will not set field value with different type.

MapStruct Version

1.4.2.Final

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions