如何使用VaultCustomQuery查询父状态的嵌套集合中的字段 [英] How to query on a field in nested collection of a parent state using VaultCustomQuery
问题描述
我有一个一对多的关系,我试图在我的状态下添加一个对象/类的列表。即
我有一个合同状态,其中包含附件列表 List< Attachment>
,其中 Attachment
是只是一类具有
attachmentHash
, uploadedDate
, fileType
I have a one-to-many relationship where I am trying to add a list of object/class in my state. i.e
I have a contract state that has a list of attachments List<Attachment>
, where Attachment
is just a class with fields like
attachmentHash
, uploadedDate
, fileType
-
我想查询子对象中的某些内容,但出现语法错误
AttachmentEntity不是PersistentState的子类型
QueryCriteria.VaultCustomQueryCriteria(
builder { (ContractSchemaV1.AttachmentEntity::uploadDate).equal(givenDate) }))
我让AttachmentEntity是 PersistentState
的子类,节点启动时出现错误
I let AttachmentEntity be a subclass of PersistentState
and the node started up with the error
org.hibernate.AnnotationException: net.corda.core.schemas.PersistentStateRef
must not have @Id properties when used as an @EmbeddedId: project.schemas.ContractSchemaV1$AttachmentEntity.stateRef
似乎就像我做错了什么,在状态中表示数据类集合并将其转换为模式的最佳方法是什么?还是这已经是正确的方法,但是无法使用 VaultCustomQuery
查询嵌套集合?
Seems like I'm doing something wrong, whats the best way to represent a collection of data classes in the state and translate that in a schema? Or is this already the correct way, but there's no way to query the nested collection using 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)
}
推荐答案
您的架构定义是正确的(您可以在此处看到另一个示例:在LinearState状态下查询嵌套集合)。
Your schema definition is correct (and you can see another example here: Querying nested collections in LinearState states).
但是, VaultCustomQueryCriteria
不支持查询嵌套集合。您必须执行直接JDBC查询才能查询嵌套集合的属性。
However, querying nested collections is not supported by VaultCustomQueryCriteria
. You have to do direct JDBC queries to query attributes of the nested collections.
以下是Corda中直接JDBC查询的示例:
Here is an example of a direct JDBC query in Corda:
@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)
}
}
这篇关于如何使用VaultCustomQuery查询父状态的嵌套集合中的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!