I have a case where I need to execute an update in a field doing a monetary operation subtract in this case. The column was created as DECIMAL(19,2) UNSIGNED
.
First I get the value:
static final String LOCK_AMOUNT_FOR_UPDATED = "select amount from Sample where uuid = :uuid for update ";
This is the repository:
@Query(value = LOCK_AMOUNT_FOR_UPDATED, nativeQuery = true)
Float getAmountForUpdate(@Param("uuid") String uuid);
Here is the first question, instead of returning Float. The recommended is returning a BigDecimal?
Then I check the values and perform an update:
static final String DECREASE_AMOUNT = "update Sample set amount = amount - :amountToSubtract where uuid = :uuid ";
Repository:
@Modifying
@Query(value = DECREASE_AMOUNT, nativeQuery = true)
void decreaseAmount(@Param("amountToSubtract") Float amountNegotiated, @Param("uuid") String uuid);
Doing this when the value is: 1927369.70
. I'm getting:
Data truncation: Out of range value for column 'amount' at row 1
The method calling is like this:
repository.decreaseNetAmount(amountNegotiated.floatValue(), uuid);
I noticed that 1927369.70
turned to 1927369.80
when I select the value and when I call .floatValue()
in BigDecimal.
What's the correct approach use everything as BigDecimal, even the parameters of nativeQuery?
I would recommend to:
Recommendations 2 and 3 are general best practices. We would need to take a broader look at the entire use case and other parts of the application to make an educated decision