Corda - VaultQuery с агрегированной суммой (поле Double в MappedSchema) - PullRequest
0 голосов
/ 09 июля 2020

Мне нужно резюмировать столбец состояния. Я создал mappedSchema и определил поле как Double. Если я перечисляю состояния, значения для этого поля верны. Но если я использую builder :: sum (), значение возвращается с проблемами округления и большим количеством десятичных знаков, чем должно.

Вот выдержки из кода:

STATE

data class ConsumerMeteringState(val metering : ConsumerMetering,
                             val meteringParticipants : List<AbstractParty> = listOf(),
                             override val linearId: UniqueIdentifier = UniqueIdentifier()) :
    LinearState, QueryableState {
override val participants: List<AbstractParty> = meteringParticipants

override fun generateMappedObject(schema: MappedSchema): PersistentState {
    return when (schema) {
        is ConsumerMeteringSchemaV1 -> ConsumerMeteringSchemaV1.PersistentConsumerMetering(
                this.metering.dateTimeIni,
                this.metering.dateTimeEnd,
                this.metering.quantityKwh,
                this.linearId.id
        )
        else -> throw IllegalArgumentException("Unrecognised schema $schema")
    }
}

override fun supportedSchemas(): Iterable<MappedSchema> = listOf(ConsumerMeteringSchemaV1)

СХЕМА

object ConsumerMeteringSchemaV1 : MappedSchema(
    schemaFamily = ConsumerMeteringSchema.javaClass,
    version = 1,
    mappedTypes = listOf(PersistentConsumerMetering::class.java)) {
@Entity
@Table(name = "consumer_metering_states")
class PersistentConsumerMetering(
        @Column(name = "date_time_ini")
        var dateTimeIni: Instant,

        @Column(name = "date_time_end")
        var dateTimeEnd: Instant,

        @Column(name = "quantity_kwh")
        var quantityKwh: Double,

        @Column(name = "linear_id")
        var linearId: UUID
) : PersistentState() {
    // Default constructor required by hibernate.
    constructor(): this(Instant.now(), Instant.now(), 0.0, UUID.randomUUID())
}

}

КРИТЕРИИ ЗАПРОСА VAULTQUERY

val criteriaAccount = QueryCriteria.VaultQueryCriteria(externalIds = listOf(accountId))
val sumQuantityKwh = builder { ConsumerMeteringSchemaV1
            .PersistentConsumerMetering::quantityKwh.sum() }
val sumQuantityKwhCriteria = QueryCriteria.VaultCustomQueryCriteria(sumQuantityKwh)
serviceHub.vaultService.queryBy(contractStateType = ConsumerMeteringState::class.java,
    criteria = criteriaAccount.and(sumQuantityKwhCriteria)).otherResults.singleOrNull()

Только состояния (значения допустимы):

[ConsumerMeteringState (metering = ConsumerMetering (dateTimeIni = 2020-06-03T09: 46: 00Z, dateTimeEnd = 2020-06-03T09: 59: 00Z, количествоKwh = 10,55 ), meteringParticipants = [Анонимные (DL624i3ieTdLkPRBUvUgZnzn5jeG3Md2cvANt6sZNJiXwy), O = Дистрибьютор, L = Куритиба, C = BR], linearId-2 ConsumerMeteringState (metering = ConsumerMetering (dateTimeIni = 2020-06-03T09: 46: 00Z, dateTimeEnd = 2020-06-03T09: 59: 00Z, amountKwh = 50,18 ), meteringParticipants = [Анонимный (DLBep6kddDduaMKVrs8) ), O = дистрибьютор, L = Куритиба, C = BR], linearId = 3b012984-676d-4e62-9b9f-1bb8158aaf4b)] * 103 0 *

С суммой строителя:

Я получаю значение 60,730000000000004

Почему сумма не возвращает 60,73?

1 Ответ

1 голос
/ 10 июля 2020

Это сработало, изменив тип столбца с Double на BigDecimal. Похоже, это вопрос точности типа Double. Я провел тест, просто получив состояния и сделав простую сумму поля amountKwh (Double), и точность была уже странной. Я не понял причину такого поведения, но с BigDecimal все работало нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...