0

I'm trying to create patch method with Mapstruct mapping and Lombok Builder. But in generated code missing build() call

Mapper with removing null values:

@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);
}

Nested classes have same lombok annotations as Cart:

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

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

All nested classes have same lombok annotations as CartRequest and structure is same as target entities structure

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

For method cartRequestToCart everything is OK, builders are called here and also in nested methods

    @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();
    }

For method patch is generated this and here in some setters missing build() call

    @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;
    }

Some tips how to fix this? Thanks a lot.

Jimi
  • 33
  • 1
  • 2
  • 10

4 Answers4

2

Update for Lombok 1.18.16.

Starting this version working configuration for maven-compiler-plugin is


<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>

The order of path sections is important!

foal
  • 693
  • 7
  • 20
1

This is a bug in MapStruct 1.3.0.Final.

I would suggest to follow mapstruct/mapstruct#1742 for the fix.

The current solution would be to completely disable the builders by setting the NoOpBuilderProvider via the SPI.

Filip
  • 19,269
  • 7
  • 51
  • 60
1

Check this worked for me even with only @Builder and @Getter

Gregory Mazur
  • 2,429
  • 4
  • 16
  • 26
0

As Gregory Mazur pointed out, this article helped me as well, but I had Maven build system. Here's Maven's config version:

  <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>