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

如何使用VaultCustomQuery查询父状态嵌套集合字段及解决子实体查询报错

如何用VaultCustomQuery查询父状态嵌套集合内的字段

你遇到的「AttachmentEntity is not a subtype of PersistentState」错误,核心原因是VaultCustomQueryCriteria只能直接作用于顶层的PersistentState实体,而你的AttachmentEntity是嵌套在父状态里的子实体,不属于顶层PersistentState类型,所以直接用它的字段构建条件会报错。下面给你一步步的解决方案:

第一步:确保Schema正确映射嵌套集合关系

首先要在你的MappedSchema里,正确定义父状态实体和子实体的关联关系,用JPA注解标记一对多/多对一的映射,确保子实体有外键关联父实体。举个Kotlin的示例:

object ContractSchemaV1 : MappedSchema(
    schemaFamily = ContractState::class.java,
    version = 1,
    mappedTypes = listOf(ContractStateEntity::class.java, AttachmentEntity::class.java)
) {
    @Entity
    @Table(name = "contract_states")
    class ContractStateEntity(
        @Column(name = "contract_id")
        val contractId: String,
        // 父状态的其他字段...
        // 标记一对多关系,关联子实体
        @OneToMany(mappedBy = "contract", cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
        val attachments: List<AttachmentEntity> = emptyList()
    ) : PersistentState() {
        // JPA要求的无参构造函数
        constructor() : this("")
    }

    @Entity
    @Table(name = "attachments")
    class AttachmentEntity(
        @Column(name = "attachment_hash")
        val attachmentHash: String,
        @Column(name = "upload_date")
        val uploadDate: Instant,
        @Column(name = "file_type")
        val fileType: String,
        // 标记多对一关系,外键关联父实体
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "contract_state_id")
        val contract: ContractStateEntity? = null
    ) {
        // JPA要求的无参构造函数
        constructor() : this("", Instant.now(), "", null)
    }
}

第二步:用Join关联父实体和子实体构建查询

既然不能直接用子实体作为查询主体,我们需要通过join方法把父实体(PersistentState类型)和子实体关联起来,然后基于子实体的字段过滤父状态。示例代码如下:

// 先构建子实体字段的查询条件
val attachmentDateCriteria = builder {
    AttachmentEntity::uploadDate.equal(Instant.parse("2024-01-01T00:00:00Z"))
}

// 关联父实体和子实体,再组合子实体的条件
val queryCriteria = QueryCriteria.VaultCustomQueryCriteria(
    builder {
        // 建立父实体和子实体的关联
        ContractStateEntity::class.java join AttachmentEntity::class.java on AttachmentEntity::contract
    }
).and(attachmentDateCriteria)

// 执行查询,返回符合条件的父状态
val matchingStates = serviceHub.vaultService.queryBy<ContractState>(queryCriteria).states

关键注意点

  • 子实体必须被包含在MappedSchema的mappedTypes列表中,否则框架无法识别它的映射关系
  • 关联时要确保on后面的字段是子实体中指向父实体的属性(比如上面的AttachmentEntity::contract)
  • 如果需要多个子实体条件,可以继续用.and()或.or()组合多个子条件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:46:08