Saltar al contenido

MapStruct QualifiedByName con múltiples parámetros

Te sugerimos que revises esta resolución en un entorno controlado antes de pasarlo a producción, un saludo.

Solución:

Actualmente, MapStruct no admite métodos de asignación con varias propiedades de origen.

Sin embargo, en su caso puede utilizar el @Context de 1.2.0. Por lo que entiendo el projId y el code están allí solo como ayudantes de la asignación, y no se utilizan para asignar propiedades de destino.

Entonces puedes hacer algo como (Debería funcionar en teoría):

@Mapper
public interface OneMapper 

    @Mapping(target="id", source="one.id")
    @Mapping(target="qualified", qualifiedByName="checkQualifiedNamed")
    OneDto createOne (One one, @Context Integer projId, @Context String code);

    @Named("checkQualifiedNamed")
    default Boolean checkQualified (One one, @Context Integer projId, @Context String code) 
        if(one.getProjectId() == projId && one.getCode().equalsIgnoreCase(code)) 
            return Boolean.TRUE;
        
        return Boolean.FALSE;                   
    

Otra alternativa sería extraer todas esas propiedades en una clase separada y pasarla (esto permitiría múltiples parámetros del mismo tipo).

La clase se vería así:

public class Filter 

    private final Integer projId;
    private final Integer val;
    private final String code;

    public Filter (Integer projId, Integer val, String code) 
        this.projId = projId;
        this.val = val;
        this.code = code;
    

    //getters

Su mapeador se verá así:

@Mapper
public interface OneMapper 

    @Mapping(target="id", source="one.id")
    @Mapping(target="qualified", qualifiedByName="checkQualifiedNamed")
    OneDto createOne (One one, @Context Filter filter);

    @Named("checkQualifiedNamed")
    default Boolean checkQualified (One one, @Context Filter filter) 
        if(one.getProjectId() == filter.getProjId() && one.getVal() == filter.getVal() && one.getCode().equalsIgnoreCase(filter.getCode())) 
            return Boolean.TRUE;
        
        return Boolean.FALSE;                   
    

A continuación, puede llamar al mapeador como: mapper.createOne(one, new Filter(projId, val, code));

Desde la versión 1.2 es compatible: http://mapstruct.org/documentation/stable/reference/html/#mappings-with-several-source-parameters

Por ejemplo como este:

@Mapping(source = "person.description", target = "description")
@Mapping(source = "address.houseNo", target = "houseNumber")
DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);

ACTUALIZAR

Dado que Mapstruct permite mapear múltiples argumentos de origen en un solo destino, recomendaría extraer el checkQualified del mapeador y, en su lugar, calcule el resultado de antemano e invoque al mapeador con el resultado del método checkQualified. Mapstruct es un cartografía librería, y no sobresale en el desempeño de la lógica arbitraria. No es imposible, pero personalmente, no veo el valor que agrega en su caso particular.

Con la lógica extraída, su mapeador podría verse así:

@Mapper
public interface OneMapper 
    OneDto toOneDto(One one, Boolean qualified);

El mapeador se puede usar así:

One one = new One(1, 10, 100, "one");
boolean qualified = checkQualified(one, 10, 100, "one");
boolean notQualified = checkQualified(one, 10, 100, "two");
OneDto oneDto = mapper.toOneDto(one, isQualified);

Para ver un ejemplo completo, consulte: https://github.com/phazebroek/so-mapstruct/blob/master/src/main/java/nl/phazebroek/so/MapStructDemo.java

Aquí puedes ver las comentarios y valoraciones de los lectores

Recuerda algo, que tienes la capacidad de parafrasear si diste con la solución.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *