-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Closed
Description
Hi,
we try to use MapStruct with Lombok builders but MapStruct does not always seem to recognize and use the builders. Our particular problematic case is when the target object has a field which only has a builder.
Used MapStruct version: 1.3.1.FINAL
Used Lombok version: 1.18.10
It would be very helpful for us if you could let us know if this is considered a bug or not.
Looking forward to your feedback!
Here is an example:
Source POJO:
package example.model.source;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Car {
private String model;
}
Target POJOs:
package example.model.target;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class CarInsurance {
private CarDetail carDetail; // this is the problematic case
}
@Data
@Builder
public class CarDetail {
private String model;
}
Mapper:
package example.mapper;
import example.model.source.Car;
import example.model.target.CarInsurance;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
@Mapper
public interface CarInsuranceMapper {
@Mapping(source = "model", target = "carDetail.model")
void map(Car source, @MappingTarget CarInsurance target);
}
MapStruct generates this mapper:
package example.mapper;
import example.model.source.Car;
import example.model.target.CarDetail;
import example.model.target.CarInsurance;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;
@Generated(
value = "org.mapstruct.ap.MappingProcessor"
)
@Component
public class CarInsuranceMapperImpl implements CarInsuranceMapper {
@Override
public void map(Car source, CarInsurance target) {
if ( source == null ) {
return;
}
if ( target.getCarDetail() == null ) {
target.setCarDetail( new CarDetail() ); // THIS CREATES A COMPILE ERROR
}
carToCarDetail( source, target.getCarDetail() );
}
protected void carToCarDetail(Car car, CarDetail mappingTarget) {
if ( car == null ) {
return;
}
mappingTarget.setModel( car.getModel() );
}
}
And the compiler fails with:
CarInsuranceMapperImpl.java:22: error: constructor CarDetail in class CarDetail cannot be applied to given types;
target.setCarDetail( new CarDetail() );
It would work if MapStruct would generate:
if ( target.getCarDetail() == null ) {
target.setCarDetail( CarDetail.builder().build() );
}
The annotation processor ordering in the Gradle build:
implementation 'org.mapstruct:mapstruct'
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.mapstruct:mapstruct-processor'
annotationProcessor 'org.projectlombok:lombok'
Reactions are currently unavailable