I want to map the mulitple fields of the Dto class to single field of entity and vice versa. How to achieve this?

54 Views Asked by At

So here, we have a Enitity class - Contact

public class Contact {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "name",nullable = false)
    private String name;
    @Column(name = "email",nullable = false,unique = true)
    private String email;
    @Column(name = "phone",nullable = false)
    private String phone;
}

A DTO class - ContactDto

public class ContactDto {
    private Long id;
    private String fname;
    private String lname;
    private String email;
    private String phone;
}

I want to map the fname and lname with the name attribute in the contact and vice versa. How to achieve this solution?

I tried using MapStruct library. I am getting confused how to implement this logic. So kindly help me either with MapStruct or ModelMapper.

@Mapper
public interface ContactMapper {
    ContactMapper INSTANCE = Mappers.getMapper(ContactMapper.class);
    ContactDto mapToContactDto(Contact contact);
    Contact mapToContact(ContactDto contactDto);
}

This is what i tried doing using Mapstruct.

3

There are 3 best solutions below

0
PawDob On

I recommend to read this question. how-to-convert-entity-to-dto-and-vice-versa

If you want to continue using MapStruct here is good explanation. Baeldung - mapstruct

Usually it is better to write your own mapper, becuase you have full controll what is happening and have less headache if some tests stop working in future.

Personally I would do like this: Of Method in Mapper

0
varnita On

You can make use of custom mapping rules in ModelMapper, create TypeMap and pass Contact and ContacoDTO as arguments. Sample code could be like:

ModelMapper modelMapper = new ModelMapper();
TypeMap<Contact , ContactDto > typeMap =     modelMapper.createTypeMap(Contact.class, ContactDto.class);
typeMap.addMappings(mapper -> {
    mapper.map(src -> src.getFirstName() + " " + src.getLastName(), ContactDto::setFullName);
});
0
Calvin P. On

To do this with MapStruct, your best bet will probably be to define a custom method for each conversion with @BeforeMapping annotation. This also requires that you change your interface to an abstract class.

@Mapper
public abstract class ContactMapper {
    ContactMapper INSTANCE = Mappers.getMapper(ContactMapper.class);
    mapToContactDto(Contact contact);
    Contact mapToContact(ContactDto contactDto);

    @BeforeMapping
    protected void splitName(Contact contact, @MappingTarget ContactDto contactDto) {
        String[] name = contact.getName().split(“ “);
        contactDto.setFname(name[0]);
        contactDto.setLname(name[1]);
    }

    @BeforeMapping
    protected void concatenateName(ContactDto contactDto, @MappingTarget Contact contact) {
        contact.setName(contactDto.getFname() + “ “ + contactDto.getLname());
    }
}

This is assuming the name is in “First Last” format in Contact. Also assumes Contact and ContactDto have standard getter/setter methods.