使用Lombok @Data注解的POJO新建实例时嵌套对象属性为null问题
问题原因与解决方案
核心原因
Lombok @Data 注解仅会为POJO生成getter、setter、equals、hashCode、toString方法以及无参构造方法(无自定义构造时),不会自动初始化任何引用类型的成员属性。按照Java基础语法规则,引用类型的类成员在实例化后默认值就是null,这是正常表现,并非Lombok或Spring Boot的bug。
你通过无参构造new RmsSearchRequestDto()创建实例时,两个嵌套POJO属性自然为null,此时直接链式调用getter就会触发空指针异常。
之前未出现问题的原因
此前你大概率没有直接通过无参构造手动实例化该DTO,而是由项目中的现有框架自动完成了嵌套对象的初始化:
- JSON反序列化框架(如Jackson)反序列化请求参数时,会自动递归实例化嵌套POJO
- Spring MVC的请求参数绑定逻辑,会自动为嵌套POJO创建实例
- 旧的自定义校验器执行前,会预先初始化所有嵌套属性
切换为Spring Bean Validation后出现问题,是因为触发场景发生了变化:要么你现在是手动new DTO后直接调用getter,要么新的校验逻辑执行时机早于参数绑定完成的节点,此时嵌套属性还未被框架初始化。
解决方案
你可以根据实际业务场景选择以下任意一种方案解决:
- 显式初始化成员属性
直接在属性定义处初始化嵌套对象,无参构造实例化后属性就不会为null:
@Data public class RmsSearchRequestDto { private AuditCredentialsDto auditCredentialsDto = new AuditCredentialsDto(); private RmsSearchCriteriaDto rmsSearchCriteriaDto = new RmsSearchCriteriaDto(); }
- 调用前做非空判断
在链式调用getter前先判断嵌套对象是否为null,避免空指针:
RmsSearchCriteriaDto criteria = rmsSearch.getRmsSearchCriteriaDto(); if (criteria != null) { String searchType = criteria.getSearchType(); // 执行业务逻辑 }
- 参数绑定场景下添加@Valid注解
如果该DTO是作为Controller的入参使用,在嵌套属性上添加@Valid注解,同时入参前添加@RequestBody/@ModelAttribute注解,Spring参数绑定逻辑会自动完成嵌套对象的实例化:
@Data public class RmsSearchRequestDto { @Valid private AuditCredentialsDto auditCredentialsDto; @Valid private RmsSearchCriteriaDto rmsSearchCriteriaDto; }
额外注意
你描述中提到的auditCredetialsDto存在拼写错误,正确字段名应为auditCredentialsDto,如果代码中存在拼写错误会导致调用getter报错,建议优先检查拼写问题。
内容的提问来源于stack exchange,提问作者Dipendra Bhandari
相关产品推荐
相关产品推荐

