205. MapStruct - dkkahm/study-springfamework5 GitHub Wiki

dependencies (build.gradle)

    compile group: 'org.mapstruct', name: 'mapstruct', version: '1.4.1.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.1.Final'

Simple Example

  • Entity
public class Car {
    private String make;
    private int numberOfSeats;
    private CarType type
    ....
}
  • DTO
public class CarDTO {
    private String make;
    private int seatCount;
    private String type;
    ....
}
  • Mapper
@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    @Mapping(source = "numberOfSeats", target = "seatCount")
    CarDto carToCarDto(Car car);
  • Test
@Test
public void shouldMapCarToDto() {
    Car car = new Car("Morris", 5, CarType.SEDAN);

    CarDto carDto = CarMapper.INSTANCE.carToCarDto(car);

    assertThat(carDto).isNotNull();
    assertThat(carDto.getMake()).isEqualTo("Morris");
    assertThat(carDto.getSeatCount()).isEqualTo(5);
    assertThat(carDto.getType()).isEqualTo("SEDAN");
}

Nest Property within Parent Mapper

  • Address is propery of User
@Mapper
public interface UserDtoMapper {
    UserDtoMapper INSTANCE = Mappers.getMapper(UserDtoMapper.class);

    @Mappings({
            @Mapping(target = "userId", ignore = true),
            @Mapping(target = "emailVerificationToken", ignore = true),
            @Mapping(target = "emailVerificationStatus", ignore = true)
    })
    UserDto UserDetailsRequestToUserDto(UserDetailsRequest userDetails);

    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(target = "encryptedPassword", ignore = true)
    })
    UserEntity UserDtoToUserEntity(UserDto userDto);

    @Mapping(target = "password", ignore = true)
    UserDto UserEntityToUserDto(UserEntity userEntity);

    UserResponse UserDtoToUserResponse(UserDto userDto);

    @Mappings({
            @Mapping(target = "addressId", ignore = true),
            @Mapping(target = "userDetails", ignore = true)
    })
    AddressDto AddressRequestMapperToAddressDto(AddressRequest addressRequest);

    @Mappings({
            @Mapping(target = "id", ignore = true)
            , @Mapping(source = "userDetails", target = "userDetails", ignore = true)
    })
    AddressEntity AddressDtoToAddressEntity(AddressDto addressDto);

    @Mapping(source = "userDetails", target = "userDetails", ignore = true)
    AddressDto AddressEntityToAddressDto(AddressEntity addressEntity);
//
//    AddressResponse AddressDtoToAddressResponse(AddressDto addressDto);
}

NESTED PROPERTY THROWS STACKOVERFLOW!!!!

SET NULL BEFORE CONVERTING !!!

AND RESTORE REFERENCE BEFORE SAVE

        for(AddressDto address : user.getAddresses()) {
            // address.setUserDetails(user); // STACKOVERFLOW !!!
            address.setAddressId(utils.generateAddressId(30));
        }

        UserEntity userEntity = UserDtoMapper.INSTANCE.UserDtoToUserEntity(user);
        for(AddressEntity address : userEntity.getAddresses()) {
            address.setUserDetails(userEntity); // Restore refrence
        }
        userEntity.setEncryptedPassword(bCryptPasswordEncoder.encode(user.getPassword()));

        UserEntity savedUserEntity = userRepository.save(userEntity);