JSF调用isSuccessfullySentToWD偶发NullPointerException原因排查
空指针异常根因
枚举值使用==比较本身不会触发空指针,这次异常的触发源只有两个可能:
isSuccessfullySentToWD()方法里调用的zoj实例本身为null。JSF的EL表达式执行时机可能早于托管Bean的属性赋值流程,比如回发请求时视图作用域Bean重建后zoj还未完成注入、或者参数绑定流程还没执行就触发了页面渲染,此时调用zoj.getStateOfDispatchToWD()会直接抛空指针。- zoj实例不为null,但它持有的
stateOfDispatchToWD枚举属性为null。你在类定义中给当前类的同名枚举字段设置的初始值StateOfDispatchToWD.NONE,仅对当前类的实例生效,完全不会作用到zoj对象的属性上。如果zoj是JPA持久化实体,数据库中对应字段存NULL值时,JPA组装实体实例会直接把该枚举字段设为null,覆盖类中写的字段初始值。因为只有部分历史数据、特定异常流程下写入的记录会带NULL值,所以异常呈现偶发特征。
修复方法
- 把判断方法改成空安全实现,从代码层兜底:
public boolean isSuccessfullySentToWD() { if (zoj == null) { return false; } return StateOfDispatchToWD.SUCCESSFULLY_DISPATCH.equals(zoj.getStateOfDispatchToWD()); }
这里直接用枚举常量调用equals方法,即使zoj的枚举字段为null,也只会返回false,不会触发空指针。
2. 给zoj对应的实体类枚举字段加非空约束,同时补全历史数据中的null值,从数据源层面避免非法值:
@Enumerated(EnumType.STRING) @Column(nullable = false) private StateOfDispatchToWD stateOfDispatchToWD = StateOfDispatchToWD.NONE;
- 检查zoj属性的初始化逻辑,确保页面渲染阶段执行EL表达式时,zoj已经完成赋值,避免实例本身为null的场景。
内容的提问来源于stack exchange,提问作者Martin Hofman
相关产品推荐
相关产品推荐

