问题
I have class A (domain class), class B (mongo db repository layer class) extends A and both of them have Lombok @Builder on them. I need to convert between them and when I use Mapstruct for this, the implementation conversion class uses Builder from A when generating object of type B. This results in build failure due to "incompatible types". How to fix this?
@Builder
class A {
}
@Document
@Builder
class B extends A{
}
@Mapper
public interface ClassMapper {
B mapToDocument(A domainObject);
}
This code generates the following Mapstruct file:
public class ClassMapperImpl implements ClassMapper{
@Override
public B mapToDocument(A domainObject){
if(domainObject == null){
return null;
}
Builder builder = A.builder();
//builder methods
return builder.build(); //incompatible types due to builder generating A objects, not B
}
}
回答1:
your code cannot compile even without the mapper. Lombok complains that the @Builder in B class has incompatible type returned:
The return type is incompatible with A.builder()
because .builder() method is static, it cannot use inheritance mechanism.
another solution is to use @Getter on A class and @Setter on B class and let mapstruct do the mapping for you.
回答2:
@Builder
does not work well in combination with inheritance. However, mapstruct also works with @SuperBuilder
, which is designed for such a use case.
Remove all @Builder
s and put @SuperBuilder
on all classes along the inheritance hierarchy.
回答3:
It's possible disable the builder, see the manual https://mapstruct.org/documentation/stable/reference/html/#mapping-with-builders
In case you want to disable using builders then you can use the NoOpBuilderProvider by creating a org.mapstruct.ap.spi.BuilderProvider file in the META-INF/services directory with org.mapstruct.ap.spi.NoOpBuilderProvider as it’s content.
this resolve the issue
来源:https://stackoverflow.com/questions/58929524/mapstruct-generated-class-uses-lombok-builder-from-parent-instead-of-child