Questions on Mapstructs.

52 views
Skip to first unread message

Baron MG

unread,
Feb 22, 2021, 5:06:03 PM2/22/21
to mapstruct-users
Hi guys,

Please, I am looking to use mapstruct in my project but wanted to understand afew things. I have two classes, an entity and a domain(dto) and a third class(Address). I have a mapper that transforms/maps a dto to the entity. I have afew comments regarding areas I am not so sure about if anyone could confirm I am doing the right thing as I am getting some errors:

//Domain/DTO
public class PersonDTO {
private String firstName;
private String lastName;
private String middleName;
private String PersonId;
private boolean isAlive;
private Optional<String> occupation;
private Adddress address;
}


//Entity class
public class Person{
private String firstName;
private String lastName;
private String fullName;
private String occupation;
private String firstLineAddress;
private String secondLineAddress;
private String postCode;
private String phoneNumber;
private String period;
private int PersonId;
}


public class Address {
private String firstLineAddress;
private String secondLineAddress;
private String postCode;
private String phoneNumber;
private int period;

}


//mapper 
@Component
@Mapper(componentModel = "spring")
public interface PersonMapper {

@Mapping(target = "isAlive", ignore = true)
@Mapping(target = "middleName", ignore = true)
@Mapping(source = "occupation",target = "occupation") //how to map this given types are different?
@Mapping(source = "address.period",target = "period") //how to map this given the types are different?
@Mapping(source = "address.firstLineAddress",target = "firstLineAddress")
@Mapping(source = "address.secondLineAddress",target = "secondLineAddress")
@Mapping(source = "address.postCode",target = "postCode")
//is this the right way to map the address object fields to the String object?
@Mapping(source = "address.phoneNumber",target = "phoneNumber")
@Mapping(target = "fullName", qualifiedByName = "getFullName")
//got an error with this

Person toPerson(final PersonDto domain);


//dynamically getting the fullName
@Named("getFullName")
default PaymentMethod getPaymentMethod(final PersonDto personDto) {
if (StringUtils.isNotBlank(personDto.getFirstName()) &&
StringUtils.isNotBlank(personDto.getFirstName())) {
return String.join(" ", personDto.getFirstName(), personDto.getFirstName());
}
return null;
}

}

Stanislav Spiridonov

unread,
Feb 24, 2021, 1:55:20 AM2/24/21
to mapstruct-users
Hi,

1. Optional<String> -> String - you need to define a custom method
2. int -> String - MapStruct will use toString(), if you need other conversation mechanisms  you need to define a custom method
3. @Mapping(target = "isAlive", ignore = true) and @Mapping(target = "middleName", ignore = true) is useless - target object does not have such properties.
4. @Mapping(target = "fullName", qualifiedByName = "getFullName") - is incorrect, use  source = ".",  using the qualifiedByName is redundantly because the custom method is unique (PersonDto -> String)
5. Check the generated PersonMapperImpl to ensure that correct mappings are generated

So

@Data
public class Address {
    private String firstLineAddress;
    private String secondLineAddress;
    private String postCode;
    private String phoneNumber;
    private int period;
}

@Data
public class PersonDto {
    private String firstName;
    private String lastName;
    private String middleName;
    private String personId;
    private boolean alive;
    private Optional<String> occupation;
    private Address address;
}

@Data
public class Person {
    private String firstName;
    private String lastName;
    private String fullName;
    private String occupation;
    private String firstLineAddress;
    private String secondLineAddress;
    private String postCode;
    private String phoneNumber;
    private String period;
    private int personId;
}

@Mapper(componentModel = "spring")
public interface PersonMapper {

    @Mapping(target = "period", source = "address.period") 
    @Mapping(target = "firstLineAddress", source = "address.firstLineAddress")
    @Mapping(target = "secondLineAddress", source = "address.secondLineAddress")
    @Mapping(target = "postCode", source = "address.postCode")
    @Mapping(target = "phoneNumber", source = "address.phoneNumber")
    @Mapping(target = "fullName", source = ".")
    Person toPerson(final PersonDto domain);

     //dynamically getting the fullName
    default String fullName(final PersonDto personDto) {
        if (StringUtils.isNotBlank(personDto.getFirstName()) && StringUtils.isNotBlank(personDto.getLastName())) {
            return String.join(" ", personDto.getFirstName(), personDto.getLastName());
        }
        return null;
    }

    default String str(final Optional<String> str) {
        return str.orElse(null);
    }

}

Best,
Stas

Reply all
Reply to author
Forward
0 new messages