You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MapStruct为何不使用带泛型的Lombok Builder?

解决MapStruct调用PagedResponse包私有构造器的问题(改用Builder实例化)

这个需求完全可行,核心是让MapStruct使用Lombok生成的Builder来创建PagedResponse实例,而非默认调用构造器。下面是两种可靠的实现方式:


方法一:通过MapStruct注解指定使用Builder

在映射器接口中,给Page<Comment>到PagedResponse<CommentResponse>的映射方法添加@BeanMapping(builder = @Builder)注解,明确告诉MapStruct使用目标类的Builder构建实例:

@Mapper(componentModel = "spring")
public interface CommentMapper {
    // 基础映射:Comment -> CommentResponse
    CommentResponse toCommentResponse(Comment comment);

    // 分页映射:Page<Comment> -> PagedResponse<CommentResponse>
    @Mapping(source = "content", target = "content")
    @Mapping(source = "number", target = "pageNumber") // 按PagedResponse字段名调整映射关系
    @Mapping(source = "size", target = "pageSize")
    @Mapping(source = "totalElements", target = "totalElements")
    @Mapping(source = "totalPages", target = "totalPages")
    @BeanMapping(builder = @Builder) // 关键注解:强制使用Builder实例化
    PagedResponse<CommentResponse> toPagedResponse(Page<Comment> page);
}

说明:

  • @BeanMapping(builder = @Builder)会覆盖MapStruct默认的构造器实例化逻辑,转而调用PagedResponse的builder()方法。
  • 需根据PagedResponse的实际字段名,手动映射Spring Data Page的对应属性(比如Page的number对应PagedResponse的pageNumber,按需调整)。
  • Lombok的@Builder默认生成公开的builder()方法,跨包也能正常访问,彻底规避包私有构造器的编译问题。

方法二:手动编写默认方法控制Builder调用

如果MapStruct的自动映射不符合预期,可在映射器中编写默认方法,完全手动处理分页转换逻辑,直接调用Builder:

@Mapper(componentModel = "spring")
public interface CommentMapper {
    CommentResponse toCommentResponse(Comment comment);

    default PagedResponse<CommentResponse> toPagedResponse(Page<Comment> page) {
        // 先映射分页内容列表
        List<CommentResponse> responseContent = page.getContent()
                .stream()
                .map(this::toCommentResponse)
                .collect(Collectors.toList());

        // 直接调用泛型Builder构建PagedResponse
        return PagedResponse.<CommentResponse>builder()
                .content(responseContent)
                .pageNumber(page.getNumber())
                .pageSize(page.getSize())
                .totalElements(page.getTotalElements())
                .totalPages(page.getTotalPages())
                // 按需添加PagedResponse的其他字段
                .build();
    }
}

说明:

  • 这种方式完全由开发者控制映射逻辑,避免MapStruct自动生成错误代码。
  • 复用已有的Comment到CommentResponse的映射方法,保证代码一致性。

补充:错误原因说明

Lombok的@Value注解默认生成包私有的全参构造器,当MapStruct生成的映射器类与PagedResponse不在同一个包时,无法访问该构造器,从而触发编译错误。而@Builder生成的builder()方法是公开的,因此通过Builder实例化是合法的。

内容的提问来源于stack exchange,提问作者Davb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:53:24