Search code examples
javaspring-bootlombokmapstruct

@Builder in Lombok with Mapstruct overrides class attribute default values


We are currently implementing in a large application the implementation of Lombok, mainly one of the advantages we want to benefit from is the use of @Builder.

For this we have implemented in Spring boot 3.2.4 the version of Lombok 1.18.30 in conjunction with Mapstruct 1.5.5.Final and the corresponding dependency to implement them lombok-mapstruct-binding:0.2.0.

The problem we are experiencing comes from the generation of the mappers. These are overwriting the initialization values of the attributes of the classes. For example:

@Column(name = "my_class_attribute",
        columnDefinition = "double default 4250")
private double my_class_attribute = 4250;

Constructing the mapper as follows:

 @Override
    public MyEntity toEntity(MyDataTransferObject source) {
        if ( source == null ) {
            return null;
        }

        MyEntity.MyEntityBuilder myEntity = MyEntity.builder();

This last line myEntity.builder(); is the one that is doing the writing of the initialization defaults.

Being an application that has a considerable amount of code we do not see maintainable and really safe to annotate with @Builder.Default those attributes that have an initialization value. This would provoke a large error margin that could not be checked at compile time.

We have reviewed other options but we do not see any that could serve globally being declared for example in a lombok.config configuration file. Any idea how to address this problem? Thank you very much for your time and help in advance.


Solution

  • I found a solution to avoid Mapstruct use the Lombok builders that are overriding the default values. You can specify the following attribute builder = @Builder(disableBuilder = true) to avoid Mapstruct use internally builders.

    A centralized config will look like that

    @MapperConfig(
            componentModel = "spring",
            nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
            nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
            unmappedTargetPolicy = ReportingPolicy.IGNORE,
            injectionStrategy = InjectionStrategy.CONSTRUCTOR,
            builder = @Builder(disableBuilder = true)
    )
    public interface MapperCentralConfig {
    
    }
    

    And a case of use

    @Mapper(config = MapperCentralConfig.class)
    public interface MyDummyMapper {