Mapstruct с @MappingTarget не вызывает lombok Builder build()

Я пытаюсь создать метод исправления с сопоставлением Mapstruct и Lombok Builder. Но в сгенерированном коде отсутствует вызов build()

Mapper с удалением нулевых значений:

@Mapper(
        nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
        nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE

)
public interface CartMapper {
    CartMapper INSTANCE = Mappers.getMapper(CartMapper.class);

    Cart cartRequestToCart(CartRequest cartRequest);

    Cart patch(CartRequest cartRequest, @MappingTarget Cart cart);
}

Вложенные классы имеют те же аннотации ломбока, что и Cart:

@Builder
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Cart {

    Customer customer;
    Owner owner;
    Integer price;
    String voucher;
}

Все вложенные классы имеют те же аннотации ломбока, что и CartRequest, и структура такая же, как и структура целевых сущностей.

@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class CartRequest {
    CustomerRequest customer;
    OwnerRequest owner;
    Integer price;
    String voucher;
}

Для метода cartRequestToCart все ок, здесь вызываются билдеры и во вложенных методах тоже

    @Override
    public Cart cartRequestToCart(CartRequest cartRequest) {
        if ( cartRequest == null ) {
            return null;
        }

        CartBuilder cart = Cart.builder();

        if ( cartRequest.getCustomer() != null ) {
            cart.customer( customerRequestToCustomer( cartRequest.getCustomer() ) );
        }
        if ( cartRequest.getOwner() != null ) {
            cart.owner( ownerRequestToOwner( cartRequest.getOwner() ) );
        }
        if ( cartRequest.getPrice() != null ) {
            cart.price( cartRequest.getPrice() );
        }
        if ( cartRequest.getVoucher() != null ) {
            cart.voucher( cartRequest.getVoucher() );
        }

        return cart.build();
    }

Для метода patch генерируется это, а здесь в некоторых сеттерах отсутствует вызов build()

    @Override
    public Cart patch(CartRequest cartRequest, Cart cart) {
        if ( cartRequest == null ) {
            return null;
        }

        if ( cartRequest.getCustomer() != null ) {
            if ( cart.getCustomer() == null ) {
                cart.setCustomer( Customer.builder() ); // HERE build() missing
            }
            customerRequestToCustomer1( cartRequest.getCustomer(), cart.getCustomer() );
        }
        if ( cartRequest.getOwner() != null ) {
            if ( cart.getOwner() == null ) {
                cart.setOwner( Owner.builder() ); // HERE build() missing
            }
            ownerRequestToOwner1( cartRequest.getOwner(), cart.getOwner() );
        }
        if ( cartRequest.getPrice() != null ) {
            cart.setPrice( cartRequest.getPrice() );
        }
        if ( cartRequest.getVoucher() != null ) {
            cart.setVoucher( cartRequest.getVoucher() );
        }

        return cart;
    }

Несколько советов, как это исправить? Большое спасибо.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
8 911
4

Ответы 4

Это ошибка в MapStruct 1.3.0.Final.

Я бы предложил следовать за структура карты/структура карты#1742 для исправления.

Текущим решением было бы полностью отключить сборщиков, установив NoOpBuilderProvider через SPI.

Проверьте этот работал на меня даже с помощью только @Builder и @Getter

Как заметил Грегори Мазур, мне тоже помог эта статья, но у меня была система сборки Maven. Вот версия конфигурации Maven:

  <dependencies>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
    </dependency>
    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-jdk8</artifactId>
      <version>1.3.1.Final</version>
    </dependency>
    ...
  </dependencies>
  ...
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration>
      <source>${maven.compiler.source}</source>
      <target>${maven.compiler.target}</target>
      <annotationProcessorPaths>
        <path>
          <groupId>org.mapstruct</groupId>
          <artifactId>mapstruct-processor</artifactId>
          <version>1.3.1.Final</version>
        </path>
        <path>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.12</version>
        </path>
      </annotationProcessorPaths>
    </configuration>
  </plugin>

Обновление для Ломбок 1.18.16.

Начиная с этой версии рабочая конфигурация для maven-compiler-plugin


<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok-mapstruct-binding</artifactId>
                <version>0.2.0</version>
            </path>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.4.1.Final</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

Порядок path разделов важен!

Другие вопросы по теме