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

Flowable部署Jackson序列化异常:CommandContextUtil.getResourceEntityManager()为空

问题:Flowable Deployment转JSON时触发NullPointerException

调用代码

public IPage<Deployment> deploymentPage(Query query, String key, String name, String tenantId) {
    DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
    if (StringUtil.isNotBlank(key)) {
        deploymentQuery.deploymentKeyLike(StringPool.PERCENT + key + StringPool.PERCENT);
    }
    if (StringUtil.isNotBlank(name)) {
        deploymentQuery.deploymentNameLike(StringPool.PERCENT + name + StringPool.PERCENT);
    }
    if (StringUtil.isNotBlank(tenantId)) {
        deploymentQuery.deploymentTenantId(tenantId);
    }
    IPage<Deployment> page = Condition.getPage(query);
    long count = deploymentQuery.count();
    List<Deployment> deployments = deploymentQuery.orderByTenantId().orderByDeploymentTime().desc().listPage((query.getCurrent() - 1) * query.getSize(), query.getSize());
    page.setRecords(deployments);
    page.setTotal(count);
    return page;
}

错误信息

Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: org.springblade.core.tool.api.R["data"]->com.baomidou.mybatisplus.extension.plugins.pagination.Page["records"]->java.util.ArrayList[0]->org.flowable.engine.impl.persistence.entity.DeploymentEntityImpl["resources"])

问题定位

序列化时触发DeploymentEntityImpl.getResources()方法,其中CommandContextUtil.getResourceEntityManager()返回null,导致空指针异常:

@Override
public Map<String, EngineResource> getResources() {
    if (resources == null && id != null) {
        List<ResourceEntity> resourcesList = CommandContextUtil.getResourceEntityManager().findResourcesByDeploymentId(id);
        resources = new HashMap<>();
        for (ResourceEntity resource : resourcesList) {
            resources.put(resource.getName(), resource);
        }
    }
    return resources;
}

解决方案

方案1:序列化时排除懒加载的resources字段

getResources()是懒加载逻辑,且依赖Flowable的命令上下文,序列化触发时上下文已不存在,导致空指针。可以通过两种方式处理:

  • 若能修改Flowable相关类,给DeploymentEntityImpl.getResources()方法添加@JsonIgnore注解,直接忽略该字段的序列化;
  • 自定义DeploymentDTO,仅包含需要返回的业务字段(如id、name、key、tenantId、deploymentTime等),将查询到的Deployment对象转换为DTO后再返回,避免触发resources的懒加载逻辑。

方案2:在Flowable命令上下文内预加载资源

Flowable的CommandContextUtil仅在Flowable命令执行流程中有效,可通过ManagementService执行命令来预加载资源,确保上下文存在:

List<Deployment> deployments = deploymentQuery.orderByTenantId().orderByDeploymentTime().desc().listPage((query.getCurrent() - 1) * query.getSize(), query.getSize());

// 在命令上下文内预加载resources,避免后续序列化时触发懒加载
managementService.executeCommand((Command<Void>) commandContext -> {
    deployments.forEach(Deployment::getResources);
    return null;
});

方案3:手动查询资源并封装

绕过Flowable的懒加载逻辑,手动查询Deployment对应的资源并封装:

List<Deployment> deployments = deploymentQuery.orderByTenantId().orderByDeploymentTime().desc().listPage((query.getCurrent() - 1) * query.getSize(), query.getSize());

// 手动查询每个Deployment的资源并处理
for (Deployment deployment : deployments) {
    List<String> resourceNames = repositoryService.getDeploymentResourceNames(deployment.getId());
    // 可选:将资源信息封装到自定义DTO,或者通过反射设置到Deployment的resources字段(如果允许)
}

内容的提问来源于stack exchange,提问作者lei qin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:34:52