corda - 如何使用 VaultCustomQuery 查询父状态的嵌套集合中的字段
问题描述
我有一个一对多的关系,我试图在我的状态中添加一个对象/类列表。即我有一个包含附件列表的合同状态,List<Attachment>
其中Attachment
只是一个具有诸如
attachmentHash
、、、uploadedDate
fileType
我想用孩子的东西查询,但我得到语法错误
"AttachmentEntity is not a subtype of 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)
}
解决方案
您的架构定义是正确的(您可以在此处查看另一个示例: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)
}
}
推荐阅读
- python - 为什么这个八边形不适合窗户?
- python - 无法访问其中包含列表的嵌套 Python 字典
- c++ - 为什么 atomic_is_lock_free 在 mac 上不能正确链接?
- tensorflow - Tensorflow Federated TFF 仍然是一个模拟环境?
- angular - Angular - 如何正确实现加载拦截器
- python - 用于 OCR 的清洁图像
- c++ - 向量双重计算以在 C++ 中找到角度
- php - Symfony 5 - 无法使用 phpunit 加载固定装置
- asp.net - 在 stimulsoft 上建立与 sql server 的连接时出现与网络相关或特定于实例的错误 错误 26 报告
- node.js - 当我尝试缩小大量文件时,Gulp Imagemin“MaxBufferError:stdout maxBuffer exceeded”