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

使用Lombok @SuperBuilder时布尔字段isInvoiced名称被修改的原因及解决方案咨询

Lombok @SuperBuilder时布尔字段isInvoiced名称被修改的原因及解决方案咨询

嘿,这个问题其实和JavaBean的命名规范、Lombok的处理逻辑,还有JSON序列化的规则都有关系,我来帮你拆解清楚:

问题根源

  1. JavaBean布尔字段的命名规范:按照JavaBean的标准,对于以is开头的布尔类型字段(比如isInvoiced),对应的getter方法应该是isInvoiced(),而不是getIsInvoiced()。Lombok在生成Builder的时候会遵循这个规范生成设置方法;同时你的JSON序列化框架(比如Jackson)也会根据getter方法名推断JSON字段名,它会自动去掉is前缀,把字段名解析为invoiced,这就是为什么你看到JSON里是"invoiced": false而非预期的"isInvoiced"。
  2. OpenAPI显示双字段的原因:SmallRye OpenAPI在生成Schema时,可能同时读取了原字段名isInvoiced和通过getter方法推断出来的invoiced,所以才会出现两个字段并存的情况。

解决方案

下面给你几个可行的解决办法,你可以根据需求选择:

方案1:调整字段命名(推荐)

直接遵循JavaBean规范,把字段名开头的is去掉,改成invoiced。这样Lombok生成的Builder方法、getter方法,还有JSON序列化的字段名都会保持一致,从根源上避免歧义:

@SuperBuilder
@Getter
@NoArgsConstructor
public class ExpenseDto {
    @NonNull
    @Size(max = 30)
    protected String recipient;

    @NonNull
    @Size(max = 30)
    protected String purpose;
    
    // ...

    protected boolean invoiced;  // 去掉is前缀,符合JavaBean规范
}

对应的Builder调用也需要同步调整:

public ExpenseEntityDto domainToEntityDto(Expense domain) {
   return ExpenseEntityDto.builder()
                .expenseId(domain.getExpenseId())
                .accountNo(domain.getAccountNo())
                .recipient(domain.getRecipient())
                .purpose(domain.getPurpose())
                .invoiced(domain.isInvoiced())  // 对应修改后的字段名
                .build();
}

这样JSON输出就会是"invoiced": false,OpenAPI Schema也只会显示一个invoiced字段。

方案2:用注解强制指定JSON字段名(不修改字段名的情况)

如果你不想改动原字段名,可以给isInvoiced字段加上@JsonProperty注解,强制指定JSON序列化的字段名称,同时确保Lombok的Builder行为符合预期:

@SuperBuilder
@Getter
@NoArgsConstructor
public class ExpenseDto {
    @NonNull
    @Size(max = 30)
    protected String recipient;

    @NonNull
    @Size(max = 30)
    protected String purpose;
    
    // ...

    @JsonProperty("isInvoiced")  // 强制指定JSON输出的字段名
    protected boolean isInvoiced;
}

这样JSON序列化的时候会输出"isInvoiced": false,同时OpenAPI Schema也只会显示isInvoiced字段,不会再出现重复的invoiced。另外,Builder的调用代码不需要改动,依然可以用.isInvoiced(domain.isInvoiced())。

额外注意点

子类ExpenseEntityDto上的@Data注解会自动生成getter/setter,对于继承来的isInvoiced字段,它生成的getter还是isInvoiced(),所以上面的解决方案同样适用于子类场景,不需要额外调整子类代码。

备注:内容来源于stack exchange,提问作者onouv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:33:11