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

时间:2018-05-07 05:55:41

标签: corda

我有一对多的关系,我试图在我的状态中添加一个对象/类列表。即 我的合同状态包含附件列表List<Attachment>,其中Attachment只是一个类似字段的类 attachmentHashuploadedDatefileType

  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
    
  3. 似乎我做错了什么,是什么最好的方式来表示状态中的数据类集合并在模式中转换它?或者这是否是正确的方法,但是无法使用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)
    }
    

1 个答案:

答案 0 :(得分:0)

您的架构定义是正确的(您可以在此处看到另一个示例: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)
    }
}