Mapstruct - dificuldade com mapeamento

1 resposta
spring-bootjpa
L

Boa noite pessoal

Tenho um projeto (spring boot, jpa) com duas classes, Car e Person, mapeadas no banco de dados com relacionamento one-to-one por meio de uma tabela intermediária. Esse relacionamento é opcional, ou seja, uma classe pode existir sem a outra.

As classes:

package examples.model;

import lombok.Data;

@Data
public class Car {

private int id;

private Person owner;

private int numerOfWheels;

private int seatingCapacity;

private double maximumVelocity;

}

package examples.dto;

import lombok.Data;

@Data
public class CarDTO {

private String id;

private String ownerId;

private String numerOfWheels;

private String seatingCapacity;

private String maximumVelocity;

}

package examples.model;

import lombok.Data;

@Data
public class Person {

private int id;

private String name;

private int age;

}

package examples.mapper;

import org.mapstruct.Mapper;

import org.mapstruct.Mapping;

import org.mapstruct.factory.Mappers;

import examples.dto.CarDTO;
import examples.model.Car;

@Mapper
public interface CarMapper {

CarMapper MAPPER = Mappers.getMapper(CarMapper.class);

@Mapping(source = dto.ownerId, target = owner.id)

Car toModel(CarDTO dto);

}

O que eu preciso é que Car.owner == null quando CarDTO.ownerId == null, ou seja, quando não for informado o id do proprietário, o atributo owner da classe Car seja nulo, senão não conseguirei persistir o objeto Car no banco de dados com um atributo <Person(id=0, name=null, age=0)>

A classe de mapeamento gerada pelo mapstruct:

package examples.mapper;

import examples.dto.CarDTO;

import examples.model.Car;

import examples.model.Person;

import javax.annotation.processing.Generated;
@Generated(

value = org.mapstruct.ap.MappingProcessor,

date = 2021-08-03T23:26:30-0300,

comments = version: 1.5.0.Beta1, compiler: Eclipse JDT (IDE) 1.3.1300.v20210419-1022, environment: Java 11.0.11 (Ubuntu)

)

public class CarMapperImpl implements CarMapper {
@Override
public Car toModel(CarDTO dto) {
    if ( dto == null ) {
        return null;
    }

    Car car = new Car();

    car.setOwner( carDTOToPerson( dto ) );
    if ( dto.getId() != null ) {
        car.setId( Integer.parseInt( dto.getId() ) );
    }
    if ( dto.getMaximumVelocity() != null ) {
        car.setMaximumVelocity( Double.parseDouble( dto.getMaximumVelocity() ) );
    }
    if ( dto.getNumerOfWheels() != null ) {
        car.setNumerOfWheels( Integer.parseInt( dto.getNumerOfWheels() ) );
    }
    if ( dto.getSeatingCapacity() != null ) {
        car.setSeatingCapacity( Integer.parseInt( dto.getSeatingCapacity() ) );
    }

    return car;
}

protected Person carDTOToPerson(CarDTO carDTO) {
    if ( carDTO == null ) {
        return null;
    }

    Person person = new Person();

    if ( carDTO.getOwnerId() != null ) {
        person.setId( Integer.parseInt( carDTO.getOwnerId() ) );
    }

    return person;
}

}

O teste:

package examples;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

import examples.dto.CarDTO;

import examples.mapper.CarMapper;

import examples.model.Car;

class CarMapperTest {

@Test
public void testMapDtoToEntity() {

CarDTO carDTO = new CarDTO();
  carDTO.setMaximumVelocity("115.2");
  carDTO.setNumerOfWheels("4");
  carDTO.setSeatingCapacity("5");
  
  Car car = CarMapper.MAPPER.toModel(carDTO);
  
  assertEquals(115.2, car.getMaximumVelocity() );
  assertEquals(4, car.getNumerOfWheels() );
  assertEquals(5, car.getSeatingCapacity());
  assertEquals(null, car.getOwner());

}

}

O resultado:

org.opentest4j.AssertionFailedError: expected: but was: <Person(id=0, name=null, age=0)>

Vejam que quando não é passado o id do proprietário, o mapstruct instancia um objeto da classe Person e coloca no atributo Car.owner

Alguém consegue me ajudar a fazer esse mapeamento?

Obrigado :slight_smile:

1 Resposta

J

Usa um expression, já deve resolver!

Exemplo:
https://stackoverflow.com/questions/62597010/mapstruct-mappingexpression-java

Criado 4 de agosto de 2021
Ultima resposta 4 de ago. de 2021
Respostas 1
Participantes 2