如何使用 VaultCustomQuery 查询父状态的嵌套集合中的字段
How to query on a field in nested collection of a parent state using VaultCustomQuery
我有一个一对多的关系,我试图在我的状态中添加 object/class 的列表。 IE
我有一个合同状态,其中有一个附件列表 List<Attachment>
,其中 Attachment
只是一个 class,其中包含如下字段
attachmentHash
、uploadedDate
、fileType
我想查询子项中的某些内容,但出现语法错误 "AttachmentEntity is not a subtype of PersistentState"
QueryCriteria.VaultCustomQueryCriteria(
builder { (ContractSchemaV1.AttachmentEntity::uploadDate).equal(givenDate) }))
我让 AttachmentEntity 成为 PersistentState
的子 class,节点启动时出现错误
org.hibernate.AnnotationException: net.corda.core.schemas.PersistentStateRef
must not have @Id properties when used as an @EmbeddedId: project.schemas.ContractSchemaV1$AttachmentEntity.stateRef
好像我做错了什么,什么是表示状态中的数据集合 classes 并将其转换为模式的最佳方式?或者这已经是正确的方法,但是无法使用 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)
}
您的架构定义是正确的(您可以在此处查看另一个示例:)。
但是,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)
}
}
我有一个一对多的关系,我试图在我的状态中添加 object/class 的列表。 IE
我有一个合同状态,其中有一个附件列表 List<Attachment>
,其中 Attachment
只是一个 class,其中包含如下字段
attachmentHash
、uploadedDate
、fileType
我想查询子项中的某些内容,但出现语法错误
"AttachmentEntity is not a subtype of PersistentState"
QueryCriteria.VaultCustomQueryCriteria( builder { (ContractSchemaV1.AttachmentEntity::uploadDate).equal(givenDate) }))
我让 AttachmentEntity 成为
PersistentState
的子 class,节点启动时出现错误org.hibernate.AnnotationException: net.corda.core.schemas.PersistentStateRef must not have @Id properties when used as an @EmbeddedId: project.schemas.ContractSchemaV1$AttachmentEntity.stateRef
好像我做错了什么,什么是表示状态中的数据集合 classes 并将其转换为模式的最佳方式?或者这已经是正确的方法,但是无法使用 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)
}
您的架构定义是正确的(您可以在此处查看另一个示例:
但是,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)
}
}