Skip to content

DeepClone mapping control not generating third tier functions to clone #3135

@mcclellanmj

Description

@mcclellanmj

Expected behavior

In 1.5.3.Final DeepClone is not working on an object that has 3 levels of nesting. However it works okay in 1.5.2.Final with the same @BeanMapping configuration

I have a nested objects as follows

Person -> Address -> ZipCode

In 1.5.2.Final it will clone all the way down to the ZipCode. In 1.5.3.Final the function to clone the ZipCode is not generated which results in a shallow copy instead of a deep one.

Mapper:

@Mapper(componentModel = "spring")
public abstract class PersonMapper {
    @BeanMapping(mappingControl = DeepClone.class, resultType = Person.class)
    public abstract Person clonePerson(Person person);
}

Behavior of this in 1.5.2.Final is below

package com.mcclellan.sdk.test.model;

import javax.annotation.processing.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-01-10T14:23:36-0600",
    comments = "version: 1.5.2.Final, compiler: javac, environment: Java 19.0.1 (Homebrew)"
)
@Component
public class PersonMapperImpl extends PersonMapper {

    @Override
    public Person clonePerson(Person person) {
        if ( person == null ) {
            return null;
        }

        Person person1 = new Person();

        person1.setFirstName( person.getFirstName() );
        person1.setLastName( person.getLastName() );
        person1.setAddress( addressToAddress( person.getAddress() ) );

        return person1;
    }

    protected ZipCode zipCodeToZipCode(ZipCode zipCode) {
        if ( zipCode == null ) {
            return null;
        }

        ZipCode zipCode1 = new ZipCode();

        zipCode1.setZipCode( zipCode.getZipCode() );
        zipCode1.setExtension( zipCode.getExtension() );

        return zipCode1;
    }

    protected Address addressToAddress(Address address) {
        if ( address == null ) {
            return null;
        }

        Address address1 = new Address();

        address1.setAddressLine1( address.getAddressLine1() );
        address1.setAddressLine2( address.getAddressLine2() );
        address1.setZipCode( zipCodeToZipCode( address.getZipCode() ) );

        return address1;
    }
}

Actual behavior

The file that was generated in 1.5.3 is, note that zip code is a direct copy

package com.mcclellan.sdk.test.model;

import javax.annotation.processing.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-01-10T14:21:54-0600",
    comments = "version: 1.5.3.Final, compiler: javac, environment: Java 19.0.1 (Homebrew)"
)
@Component
public class PersonMapperImpl extends PersonMapper {

    @Override
    public Person clonePerson(Person person) {
        if ( person == null ) {
            return null;
        }

        Person person1 = new Person();

        person1.setFirstName( person.getFirstName() );
        person1.setLastName( person.getLastName() );
        person1.setAddress( addressToAddress( person.getAddress() ) );

        return person1;
    }

    protected Address addressToAddress(Address address) {
        if ( address == null ) {
            return null;
        }

        Address address1 = new Address();

        address1.setAddressLine1( address.getAddressLine1() );
        address1.setAddressLine2( address.getAddressLine2() );
        address1.setZipCode( address.getZipCode() );

        return address1;
    }
}

Steps to reproduce the problem

Use an @BeanMapping(mappingControl=DeepClone.class) on an object that has 3 levels of nesting to it.
When looking at the generated java file the third level of nesting will be direct copy instead of having a clone method created for it.

@Mapper(componentModel = "spring")
public abstract class PersonMapper {
    @BeanMapping(mappingControl = DeepClone.class, resultType = Person.class)
    public abstract Person clonePerson(Person person);
}

MapStruct Version

1.5.3.Final

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions