TypedQuery serviceHub.withEntityManager返回消耗状态

时间:2020-04-17 11:09:12

标签: corda

我的问题类似于serviceHub.vaultQueryService.queryBy returns all related states by default?,除了我们为状态映射了模式并使用TypedQueries从数据库中获取状态。

从数据库查询状态的流程:

@StartableByRPC
@Transactional
open class FetchServiceById(
    private val serviceId: UniqueIdentifier
) : FlowLogic<List<ServiceSchemaV1.PersistentService>>() {

    @Suspendable
    override fun call(): List<ServiceSchemaV1.PersistentService> {

        return serviceHub.withEntityManager {
            createQuery(
                "SELECT s FROM $TABLE_NAME s WHERE s.linearId = ?1",
                ServiceSchemaV1.PersistentService::class.java
            ).setParameter(
                1,
                serviceId.id
            ).resultList
        }
    }

    private companion object {
        val TABLE_NAME = ServiceSchemaV1.PersistentService::class.jvmName
    }
}

这将正确返回状态,但是在更新特定状态并再次运行查询后,它将同时返回旧的消耗状态和新的未消耗状态。

我检查了h2数据库,可以看到状态更新后,VAULT_STATE中的CONSUMED_TIMESTAMP中有一个日期,其STATE_STATUS为1。

我们如何仅使用类型化查询来查询未使用状态?我知道我们可以只使用linearquery,但是当我们需要查询和连接来自不同状态的数据时,我认为这在计算上是不可行的。

状态使用的模式


object ServiceSchema

object ServiceSchemaV1 : MappedSchema(
    schemaFamily = ServiceSchema.javaClass,
    version = 1,
    mappedTypes = listOf(
        PersistentService::class.java
    )) {
    @Entity
    @Table(name = "service_states")

    class PersistentService(
        @Column(name = "accountoperator")
        var accountOperator: String,

        @Column(name = "serviceprovider")
        var serviceProvider: String,

        @Column(name = "servicename")
        var serviceName: String,

        @Column(name = "servicedescription")
        var serviceDescription: String,

        @Column(name = "datacreated")
        var dataCreated: LocalDate,

        @Column(name = "linear_id")
        var linearId: UUID,

        @ElementCollection
        @Column(name = "service_data_ids")
        var serviceDataIds: MutableList<UUID>,

        @ElementCollection
        @Column(name = "service_partners")
        var servicePartners: MutableList<String>

    ) : PersistentState() {
        constructor() : this(
            "",
            "",
            "",
            "",
            LocalDate.now(),
            UUID.randomUUID(),
            mutableListOf(),
            mutableListOf()
        )
    }
}

2 个答案:

答案 0 :(得分:0)

您可以基于TRANSACTION_ID和OUTPUT_INDEX对州的架构和VAULT_STATE表执行联接查询,并根据STATE_STATUS进行过滤。

Select X, Y Z, from MY_STATE M, VAULT_STATES V WHERE M.TRANSACTION_ID = 
V.TRANSACTION_ID AND M.OUTPUT_INDEX = V.OUTPUT_INDEX AND STATE_STATUS = 0

答案 1 :(得分:0)

您应检查此服务呼叫是否包括所有必要的参与者。否则,您只能看到特定节点包含在上次状态更新的合同中的状态。