我有一对多的关系,我试图在我的状态中添加一个对象/类列表。即
我的合同状态包含附件列表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)
}
答案 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)
}
}