添加SmartEdit组件时AttributeDescriptorModel.getLocalized()空指针异常
问题详情
添加SmartEdit组件过程中,调用AttributeDescriptorModel.getLocalized()时出现NullPointerException,报错提示该方法返回null,导致无法调用booleanValue()。尝试用Groovy脚本查询存在问题的模型,但未找到结果,且生产环境无法调试。
原排查脚本
def SCRIPT_QUERY = "select {pk} from {attributeDescriptor}" def attributeDescriptors = flexibleSearchService.search(SCRIPT_QUERY).getResult()println ("groovy start-----------")for (attributeDescriptor in attributeDescriptors) {if(attributeDescriptor.getLocalized()==null){println(attributeDescriptor.getName())}}println ("groovy end-----------")
报错日志
loggerName":"de.hybris.platform.webservicescommons.resolver.AbstractRestHandlerExceptionResolver","message":"java.lang.NullPointerException:
Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "de.hybris.platform.core.model.type.AttributeDescriptorModel.getLocalized()" is null
at de.hybris.platform.cms2.common.predicates.IsCollectionAttributePredicate.test(IsCollectionAttributePredicate.java:21)
at de.hybris.platform.cms2.common.predicates.IsCollectionAttributePredicate.test(IsCollectionAttributePredicate.java:17)
at de.hybris.platform.cmsfacades.types.populator.DropdownComponentTypeAttributePopulator.populate(DropdownComponentTypeAttributePopulator.java:38)
at de.hybris.platform.cmsfacades.types.populator.DropdownComponentTypeAttributePopulator.populate(DropdownComponentTypeAttributePopulator.java:25)
at de.hybris.platform.cmsfacades.types.converter.ComponentTypeStructureConverter.lambda$convertAttribute$5(ComponentTypeStructureConverter.java:183)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at de.hybris.platform.cmsfacades.types.converter.ComponentTypeStructureConverter.convertAttribute(ComponentTypeStructureConverter.java:183)
排查与解决办法
1. 缩小Groovy查询范围
原脚本遍历所有AttributeDescriptor,范围太广。问题出在CMS组件相关属性上,调整脚本只查询这类属性:
def SCRIPT_QUERY = "SELECT {ad.pk} FROM {AttributeDescriptor AS ad JOIN Type AS t ON {ad.enclosingType} = {t.pk}} WHERE {t.code} LIKE 'CMS%Component'" def attributeDescriptors = flexibleSearchService.search(SCRIPT_QUERY).getResult() println("groovy start-----------") for (attributeDescriptor in attributeDescriptors) { def localized = attributeDescriptor.getLocalized() if (localized == null) { println("属性名: ${attributeDescriptor.getName()}, 所属类型: ${attributeDescriptor.getEnclosingType().getCode()}, PK: ${attributeDescriptor.getPk()}") } } println("groovy end-----------")
2. 直接检查数据库
登录数据库执行SQL,找localized字段为null的记录:
SELECT pk, name, enclosingtypepk FROM attributedescriptor WHERE localized IS NULL;
找到对应记录后,通过Hybris后台Type System模块,找到该属性所属的CMS组件类型,修复Localized配置(设为true或false)。
3. 临时代码修复(无法改数据库时)
扩展原IsCollectionAttributePredicate类,增加null判断:
public class CustomIsCollectionAttributePredicate implements Predicate<AttributeDescriptorModel> { @Override public boolean test(AttributeDescriptorModel attributeDescriptorModel) { Boolean localized = attributeDescriptorModel.getLocalized(); return attributeDescriptorModel.isCollection() && (localized == null ? false : !localized.booleanValue()); } }
通过Spring配置替换原bean,避免NPE触发。
4. 检查自定义扩展配置
排查项目中自定义的CMS组件扩展,确认所有属性都正确配置了localized属性,避免生成的AttributeDescriptorModel中该字段为null。
内容的提问来源于stack exchange,提问作者Naved Ali

