Mapstruct生成的类使用来自父级而不是子级的龙目岛生成器



我有类A(域类),B类(mongo db存储库层类)扩展A,它们都有龙目岛@Builder。我需要在它们之间进行转换,当我为此使用 Mapstruct 时,实现转换类在生成 B 类型的对象时使用 A 中的生成器。这会导致由于"不兼容类型"而导致生成失败。如何解决这个问题?

@Builder
class A {
}
@Document
@Builder
class B extends A{
}
@Mapper
public interface ClassMapper {
B mapToDocument(A domainObject);
}

此代码生成以下 Mapstruct 文件:

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

即使没有映射器,您的代码也无法编译。龙目岛抱怨 B 类中的@Builder返回了不兼容的类型:

返回类型与 A.builder() 不兼容

因为 .builder() 方法是静态的,所以它不能使用继承机制。

另一种解决方案是在 A 类上使用 @Getter,在 B 类上使用@Setter,让 mapstruct 为您完成映射。

可以禁用构建器,请参阅手册 https://mapstruct.org/documentation/stable/reference/html/#mapping-with-builders

如果你想

禁用使用构建器,那么你可以通过在META-INF/services目录中创建一个org.mapstruct.ap.spi.BuilderProvider文件来使用NoOpBuilderProvider,并将org.mapstruct.ap.spi.NoOpBuilderProvider作为其内容。

这解决了问题

有同样的问题。通过向孩子添加@SuperBuilder注释来解决它

@Builder

不能很好地与继承结合使用。但是,mapstruct 也可以与@SuperBuilder一起使用,后者是为这样的用例而设计的。

删除所有@Builder,并@SuperBuilder继承层次结构中的所有类。

最新更新