Reputation: 81
I need to summarize a column of a state. I created a mappedSchema and defined the field as Double. If I list the states, the values for that field are correct. But if I use builder::sum(), the value returns with rounding problems and more decimal places than it should.
Here are excerpts from the code:
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)
SCHEMA
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 CRITERIA
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()
States only (the values are OK):
[ConsumerMeteringState(metering=ConsumerMetering(dateTimeIni=2020-06-03T09:46:00Z, dateTimeEnd=2020-06-03T09:59:00Z, quantityKwh=10.55), meteringParticipants=[Anonymous(DL624i3ieTdLkPRBUvUgZnzn5jeG3Md2cvANt6sZNJiXwy), O=Distributor, L=Curitiba, C=BR], linearId=2e5009ad-56c3-4fed-ba36-deb0d48e668c), ConsumerMeteringState(metering=ConsumerMetering(dateTimeIni=2020-06-03T09:46:00Z, dateTimeEnd=2020-06-03T09:59:00Z, quantityKwh=50.18), meteringParticipants=[Anonymous(DLBep6kdDduaMKVrszQWa7N8i6YNnJLtA4WXsp4QmZiEjC), O=Distributor, L=Curitiba, C=BR], linearId=3b012984-676d-4e62-9b9f-1bb8158aaf4b)]
With builder sum:
I get the value 60.730000000000004
Why sum doesn't return 60.73 ?
Upvotes: 0
Views: 76
Reputation: 81
It worked by changing the column type from Double to BigDecimal. It seems to be some question of precision of the Double type. I did a test just by retrieving the states and making a simple sum of the quantityKwh (Double) field and the precision was already strange. I didn't understand the reason for this behavior, but with BigDecimal it worked ok.
Upvotes: 1