Как выполнить запрос к полю во вложенной коллекции родительского состояния с помощью VaultCustomQuery - PullRequest
0 голосов
/ 07 мая 2018

У меня есть отношение один ко многим, когда я пытаюсь добавить список объекта / класса в моем состоянии. т.е. У меня есть состояние контракта, в котором есть список вложений List<Attachment>, где Attachment это просто класс с такими полями, как attachmentHash, uploadedDate, fileType

  1. Я хотел запросить что-то в дочернем элементе, но я получил синтаксическую ошибку "AttachmentEntity is not a subtype of PersistentState"

    QueryCriteria.VaultCustomQueryCriteria(
    builder { (ContractSchemaV1.AttachmentEntity::uploadDate).equal(givenDate) })) 
    
  2. Я позволил 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)
}

1 Ответ

0 голосов
/ 08 мая 2018

Ваше определение схемы правильное (и вы можете увидеть другой пример здесь: Запрос вложенных коллекций в состояниях LinearState ).

Однако запрос вложенных коллекций не поддерживается VaultCustomQueryCriteria.Вы должны выполнять прямые JDBC-запросы для запроса атрибутов вложенных коллекций.

Вот пример прямого JDBC-запроса в 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)
    }
}
...