Я пытаюсь создать метод исправления с сопоставлением 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;
}
Несколько советов, как это исправить? Большое спасибо.




Это ошибка в 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 разделов важен!