首页 > 解决方案 > Corda - 查询 QueryableState 子表

问题描述

背景

我无法在示例 Corda 应用程序中查询子数据,演示如何使用QueryableState.

以供参考:

汽车保险示例演示了如何设置:

问题

汽车保险样本没有展示的是如何查询该数据。构建 Vault 查询PersistentInsurance相当简单,因为我们可以使用它VaultCustomQueryCriteria来构建基于 的属性的自定义查询表达式PersistentInsurance,但是对于层次结构中的子表来说并非如此。这是因为PersistentInsuranceextends PersistentState,而PersistentVehiclePersistentClaimdon't 。

对于 Reference,其底层类型层次结构PersistentState如下:

StatePersistable> DirectStatePersistable>PersistentState

interface StatePersistable

interface DirectStatePersistable : StatePersistable {
    val stateRef: PersistentStateRef?
}

class PersistentState(@EmbeddedId override var stateRef: PersistentStateRef? = null) : DirectStatePersistable

data class PersistentStateRef(
        @Suppress("MagicNumber") // column width
        @Column(name = "transaction_id", length = 144, nullable = false)
        var txId: String,

        @Column(name = "output_index", nullable = false)
        var index: Int
) : Serializable {
    constructor(stateRef: StateRef) : this(stateRef.txhash.toString(), stateRef.index)
}

回到汽车保险样本,我们不能使用VaultCustomQueryCriteriaforPersistentVehiclePersistentClaimasVaultCustomQueryCriteria::expression对 有一个通用约束StatePersistable

data class VaultCustomQueryCriteria<L : StatePersistable>(
    val expression: CriteriaExpression<L, Boolean>,
    ...
) : CommonQueryCriteria() { ... }

我试过的

当您使用这些类中的任何属性创建 a 时StatePersistable,实现PersistentVehicle和/或PersistentClaim导致以下错误:VaultCustomQueryCriteria

net.corda.core.node.services.VaultQueryException:解析错误:无法在此 ManagedType [...$PersistentClaim] 上找到具有给定名称 [stateRef] 的属性

在完成事务时执行DirectStatePersistablePersistentState打开PersistentVehicle和/或PersistentClaim导致内部错误。流挂起并最终超时。由于代码隐藏在底层 Corda 服务的内部实现中,我无法准确确定错误发生的位置。

什么有效(容量有限)

我知道我们可以执行自定义 SQL 查询;例如:

val sqlQuery = buildString {
    appendln("SELECT TRANSACTION_ID, OUTPUT_INDEX")
    appendln("FROM CLAIM_DETAIL")
    appendln("WHERE claimNumber = '123'")
}

val stateRefs = serviceHub.jdbcSession().executeCaseInsensitiveQuery(sqlQuery).map {
    val txId = SecureHash.parse(it.getString("TRANSACTION_ID")
    val index = it.getInt("OUTPUT_INDEX")
    StateRef(txId, index)
}.toList().toBlocking().first()

VaultQueryCriteria(stateRefs = stateRefs)

不用说,与以下相比,这很可怕:

VaultCustomQueryCriteria(PersistentClaim::claimNumber.equal("123"))

至于为什么它以有限的容量工作,这对于节点内部的查询很有效,它可以访问服务中心,但不能通过 RPC 工作,因为无法访问jdbcSession.

那么,关于我们如何提高子表的查询能力的任何想法(如果可能的话)?

标签: corda

解决方案


@Matthew Layton 我已将您的担忧提交给工程团队。团队对此进行了调查。

要解决/修复此问题,需要进行大量平台更改。

暂时我建议您使用本机查询进行管理。我们计划优先考虑这个问题。我会及时通知你。


推荐阅读