首页 > 解决方案 > 如何使用 VaultCustomQuery 查询父状态的嵌套集合中的字段

问题描述

我有一个一对多的关系,我试图在我的状态中添加一个对象/类列表。即我有一个包含附件列表的合同状态,List<Attachment>其中Attachment只是一个具有诸如 attachmentHash、、、uploadedDatefileType

  1. 我想用孩子的东西查询,但我得到语法错误"AttachmentEntity is not a subtype of PersistentState"

    QueryCriteria.VaultCustomQueryCriteria(
    builder { (ContractSchemaV1.AttachmentEntity::uploadDate).equal(givenDate) })) 
    
  2. 我让 AttachmentEntity 成为的子类,PersistentState并且节点以错误启动

    org.hibernate.AnnotationException: net.corda.core.schemas.PersistentStateRef 
    must not have @Id properties when used as an @EmbeddedId: project.schemas.ContractSchemaV1$AttachmentEntity.stateRef
    

好像我做错了什么,表示状态中的数据类集合并将其转换为模式的最佳方法是什么?或者这已经是正确的方法,但是没有办法使用 ? 查询嵌套集合VaultCustomQuery

下面的示例实体。

object ContractSchema

 object ContractSchemaV1 : MappedSchema(schemaFamily = ContractSchema.javaClass, version = 1,
    mappedTypes = listOf(ContractEntity::class.java, AttachmentEntity:class.java)) {
@Entity
@Table(name = "contracts")
class ContractEntity(

        @Column(name = "issued_date")
        var issuedDate: Instant,

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

        @OneToMany(fetch = FetchType.LAZY, cascade = arrayOf(CascadeType.PERSIST))
        @JoinColumns(
                JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"),
                JoinColumn(name = "output_index", referencedColumnName = "output_index"))
        var attachments: MutableSet<AttachmentEntity> = emptyList(),

) : PersistentState()

@Entity
@Table(name = "attachments")
class AttachmentEntity (

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    var id: Long? = null,

    @Column(name = "attachment_hash", nullable = false)
    var attachmentHash: String? = null,

    @Column(name = "attachment_name", nullable = false)
    var attachmentName: String? = null,

    @Column(name = "upload_date", nullable = true)
    var uploadDate: Instant? = null)
}

标签: corda

解决方案


您的架构定义是正确的(您可以在此处查看另一个示例:Querying nested collections in LinearState states)。

但是,不支持查询嵌套集合VaultCustomQueryCriteria。您必须执行直接 JDBC 查询来查询嵌套集合的属性。

以下是 Corda 中直接 JDBC 查询的示例:

@Test
fun `test calling an arbitrary JDBC native query`() {
    val nativeQuery = "SELECT v.transaction_id, v.output_index FROM vault_states v WHERE v.state_status = 0"

    database.transaction {
        val jdbcSession = services.jdbcSession()
        val prepStatement = jdbcSession.prepareStatement(nativeQuery)
        val rs = prepStatement.executeQuery()
        var count = 0
        while (rs.next()) {
            val stateRef = StateRef(SecureHash.parse(rs.getString(1)), rs.getInt(2))
            Assert.assertTrue(cashStates.map { it.ref }.contains(stateRef))
            count++
        }
        Assert.assertEquals(cashStates.count(), count)
    }
}

推荐阅读