You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过QueryCriteria按userName查询UserState以规避数量限制报错?

Can I use QueryCriteria to query UserState by userName?

Yes, you absolutely can use QueryCriteria to filter UserState by userName directly at the database level—and this is the right approach to fix your large dataset pagination issue. Your current method pulls all states into memory first, which hits Corda's default 200-record page limit when you have more than 201 users. Using a custom criteria pushes the filtering to the database, making the query efficient and avoiding the error.

Here's how to implement it step by step:

1. Ensure your UserState is persistently mapped

First, you need to map your UserState to a database entity so Corda can query its fields directly. Add JPA annotations and implement QueryableState:

import net.corda.core.contracts.BelongsToContract
import net.corda.core.contracts.LinearState
import net.corda.core.contracts.QueryableState
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Table
import java.util.UUID

@BelongsToContract(UserContract::class)
@Entity
@Table(name = "user_states")
data class UserState(
    val userName: String,
    // Add your other state fields here
    override val linearId: UniqueIdentifier = UniqueIdentifier()
) : LinearState, QueryableState {

    override fun generateMappedObject(schema: MappedSchema): PersistentState {
        return when (schema) {
            is UserSchemaV1 -> PersistentUserState(
                userName = this.userName,
                linearId = this.linearId.id,
                externalId = this.linearId.externalId
            )
            else -> throw IllegalArgumentException("Unrecognized schema: $schema")
        }
    }

    override fun supportedSchemas(): Iterable<MappedSchema> {
        return listOf(UserSchemaV1)
    }
}

// Define the database schema for UserState
object UserSchemaV1 : MappedSchema(
    schemaFamily = UserSchema::class.java,
    version = 1,
    mappedTypes = listOf(PersistentUserState::class.java)
)

@Entity
@Table(name = "user_states")
class PersistentUserState(
    @Column(name = "user_name", nullable = false)
    var userName: String,

    @Column(name = "linear_id", nullable = false)
    var linearId: UUID,

    @Column(name = "external_id")
    var externalId: String?
) : PersistentState()

// Dummy contract class (replace with your actual contract)
class UserContract

2. Build the custom QueryCriteria

Use VaultCustomQueryCriteria with a JPA criteria query to filter by userName:

val userName = "Bob"

// Create a JPA criteria query targeting the persistent UserState entity
val criteriaBuilder = proxy.entityManager.criteriaBuilder
val query = criteriaBuilder.createQuery(PersistentUserState::class.java)
val root = query.from(PersistentUserState::class.java)
query.select(root).where(criteriaBuilder.equal(root.get("userName"), userName))

// Wrap the JPA query in a Corda VaultCustomQueryCriteria
val customCriteria = VaultCustomQueryCriteria(query)

// Execute the query
val userStates = proxy.vaultQueryBy<UserState>(criteria = customCriteria).states

Key Notes

  • This approach filters records at the database level, so you only fetch the states matching your userName—no more pulling hundreds of records into memory.
  • Make sure your node's configuration includes the schema (it should auto-detect if your state is in a deployed CorDapp).
  • You can extend this to add additional filters (like state status) by combining criteria with QueryCriteria.and() or QueryCriteria.or().

内容的提问来源于stack exchange,提问作者pozita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:33:50