Lombok @Builder注解踩坑记录

2023-06-09 21:13:07 浏览数 (2)

Lombok是一款Java开发中常用的工具库,它提供了许多注解,可以简化代码的编写。其中,@Builder注解可以帮助我们快速生成Builder模式的代码,但在使用过程中,我们也需要注意一些细节,否则可能会出现一些问题。下面分享一些我在实际开发中遇到的问题,希望大家引以为戒。

1. 事件背景

在预发环境测试时,Kafka消费出现告警,经排查后发现原因是数据插入失败,一直在重试。本次在数据库中新增了字段,所以很快定位到问题出在了新字段上。

2. 排查经过

  • 数据库新增字段中声明了NOT NULL,但代码在中赋了NULL值,导致插入失败;
  • 进一步排查所有给新增字段赋值的代码,发现了一处lombok注解:
代码语言:java复制
// 这里简化了业务类,只是为了说明情况
import lombok.Data;

@Data
public class Reason {
  // ...业务字段
  private String id;
  
  @Builder
  @Getter
  @ToString
  public static class Param {
    // ...业务字段
    private long type;
    
    private String opUserName = "";
  }
}
  • 调用这处builder类的业务逻辑,没有为opUserName字段赋值:
代码语言:java复制
@Service
public class Service {
  // ...业务逻辑略
  
  // 调用
  public void call() {
    // ...业务逻辑略
    Reason.Param param = Reason.Param.builder().type(type);
    // ...业务逻辑  
  }
}

3. 原因

  • 在使用@Builder注解时,Lombok会为该类生成一个Builder类,该Builder类中会包含该类的所有字段,并且每个字段都有一个对应的set方法。在使用Builder类构建该类的实例时,通过调用build方法为每个字段赋值,进而调用了set方法。set方法内容大致如下:
代码语言:java复制
public static class ParamBuilder {
  // ...略过其他代码
  
  // 对应的set方法,这里以reason为例子
  public Param.ParamBuilder opUserName(String opUserName) {
    this.opUserName = opUserName;
    return this;
  }
}
  • 在Build时,Lombok会执行对应的set方法,但方法中没有为默认值做特殊处理。因此如果在build时没有肤质,则会默认赋NULL值覆盖,因此导致最终返回NULL;

4. 解决方案

为了避免这样问题的出现,我们可以采取以下措施:

  • 在使用@Builder注解时,尽量不要为字段设置默认值,而是在Builder.build()方法中为所有字段都赋值。
  • 如果必须为字段设置默认值,那么在Builder.build()方法中也要为该字段赋值,以确保不会出现null值。
  • 在数据库设计时,尽量避免使用NOT NULL声明,或在代码中对所有字段进行非空判断,避免出现空指针异常。

总之,最终还是有惊无险的解决了问题,还好是预发环境。

0 人点赞