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

Corda 如何使用Vault CustomQuery查询父状态的嵌套集合中的字段,corda,Corda,我有一个一对多的关系,我试图在我的状态中添加一个对象/类列表。即 我有一个合同状态,它有一个附件列表list,其中Attachment只是一个带有如下字段的类 attachmentHash,上传日期,文件类型 我想查询子对象中的某些内容,但得到语法错误“AttachmentEntity不是PersistentState的子类型” QueryCriteria.VaultCustomQueryCriteria( builder { (ContractSchemaV1.AttachmentEntity

我有一个一对多的关系,我试图在我的状态中添加一个对象/类列表。即 我有一个合同状态,它有一个附件列表
list
,其中
Attachment
只是一个带有如下字段的类
attachmentHash
上传日期
文件类型

  • 我想查询子对象中的某些内容,但得到语法错误“AttachmentEntity不是PersistentState的子类型”

    QueryCriteria.VaultCustomQueryCriteria(
    builder { (ContractSchemaV1.AttachmentEntity::uploadDate).equal(givenDate) })) 
    
  • 我将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)
    }
    
    对象模式
    对象ContractSchemaV1:MappedSchema(schemaFamily=ContractSchema.javaClass,版本=1,
    mappedTypes=listOf(ContractEntity::class.java,AttachmentEntity:class.java)){
    @实体
    @表(name=“合同”)
    类合同实体(
    @列(name=“发布日期”)
    var发行日期:即时,
    @列(name=“linear\u id”)
    var-linearId:String,
    @OneToMany(fetch=FetchType.LAZY,cascade=arrayOf(CascadeType.PERSIST))
    @连接柱(
    JoinColumn(name=“transaction\u id”,referencedColumnName=“transaction\u id”),
    JoinColumn(name=“输出索引”,referencedColumnName=“输出索引”))
    变量附件:MutableSet=emptyList(),
    ):PersistentState()
    @实体
    @表(name=“附件”)
    类附件(
    @身份证
    @GeneratedValue(策略=GenerationType.IDENTITY)
    @列(name=“id”,unique=true,nullable=false)
    变量id:Long?=null,
    @列(name=“attachment\u hash”,null=false)
    var attachmentHash:String?=null,
    @列(name=“attachment\u name”,nullable=false)
    var attachmentName:字符串?=null,
    @列(name=“upload\u date”,null=true)
    var uploadDate:即时?=null)
    }
    
    您的模式定义是正确的(您可以在这里看到另一个示例:)

    但是,
    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)
        }
    }
    

    只是澄清一下,所以实体中的子对象不应该是PersistentState的子类,对吗?如何更新状态?我遇到主键冲突。您可以分享一些示例吗。Corda OS 4.6是否支持通过
    VaultCustomQueryCriteria
    查询嵌套集合?2018年这是不可能的,但两年后情况可能已经改变。