2014-05-11 1 views
3

MySQL 데이터베이스에서 읽은 BigDecimal에서 Joda-Money Money 객체를 만들려고하면 오류가 발생합니다.ResultSet :: getBigDecimal이 joda-money에 대한 scale 예외를 throw합니다.

이 코드 :이의 의심 오전

Money amount = Money.of(CurrencyUnit.USD, results.getBigDecimal("amount"), RoundingMode.HALF_UP); 

그러나 :

java.lang.ArithmeticException: Scale of amount 1.0000 is greater than the scale of the currency USD 
    at org.joda.money.Money.of(Money.java:74) 
    at core.DB.getMoney(DB.java:4821) 

내가 실제로 라운딩을 추가하여 오류를 해결 한 :

PreparedStatement p_stmt = ...; 
ResultSet results = ...; 
Money amount = Money.of(CurrencyUnit.USD, results.getBigDecimal("amount")); 

이 예외 해결책. 최고야?.

나는 this SO answer에 따라 DB에 금액을 저장하기 위해 DECIMAL(19,4)을 사용하고 있습니다. 정직하게 말하면, 그것은 혼란 스러웠습니다. 그 이유는 응답자가 DB에 소수점 이하 4 자리를 요구했기 때문입니다.하지만 저는 고수준 응답을 신뢰하는 경향이 있으며, 그들이 말하는 내용을 알고 있다고 가정하고 그 내용을 따르지 않을 것을 후회할 것입니다. 조언. 그러나 Joda-Money는 미국 통화로 소수점 이하 4 자리를 좋아하지 않습니다. 어쩌면 DECIMAL(19,4)은 소수점 이하 4 자리를 필요로하는 국제 표준 이었습니까? 확실하지 ..

는 질문에 간결하게하려면

  1. RoundingMode.HALF_UP이 오류를 해결하는 이상적인 솔루션인가?
  2. MySQL 데이터베이스의 정밀도를 DECIMAL(19,4)에서 DECIMAL(19,2)으로 변경해야합니까?
  3. Joda-Money의 정밀도를 변경하는 방법이 있습니까? 그렇다면 :해야합니까?

답변

0

예, 좋은 해결책은 아닙니다. 당신은 돈을 대변하고 있습니다, 따라서 U는 몇 센트를 올리거나 내릴 수 없습니다 :).

CurrencyUnit.USD의 자릿수는 2입니다 (예 : 1.45). DB에서 가져온 값은 1.45343과 같은 것으로 축척이 달라질 수 있습니다. Money 대신 BigMoney로 돈을 표현하십시오.

BigMoney amount = BigMoney .of(CurrencyUnit.USD, results.getBigDecimal("amount")); 
+0

글쎄, 당신은 센트를 잃지 않을 것입니다. 'BigDecimal'''HALF_UP'을'Money' 객체의 스케일로 반올림하기 때문에 센트의 일부를 닫을 수 있습니다. – ryvantage

0

했다 동일한 문제 및 불필요한 반올림 모드를 추가하여 그것을 해결 :

@Test(dataProvider = "moneyValueProvider") 
    public void testMoneyFromFloat(String currency, Float value) { 
     CurrencyUnit cu = CurrencyUnit.of(currency); 
     //Double dVal = Double.valueOf(value.toString()); 
     BigDecimal bigDecimal = new BigDecimal(value.toString()); 
     Money money = Money.of(cu, bigDecimal, RoundingMode.UNNECESSARY); 
     Assert.assertNotNull(money); 
     Assert.assertEquals(bigDecimal.doubleValue(), money.getAmount().doubleValue()); 
    } 

    @DataProvider 
    public static Object[][] moneyValueProvider() { 
     return new Object[][] { 
        {"GBP", 22.5f}, 
        {"GBP", 57.8f}, 
        {"JPY", 15000.0f} 

    }; 
+0

'RoundingMode.UNNECESSARY'을 본 적이 없습니다. 그러나 여전히 하나의 질문이 계속됩니다 :'DECIMAL (19,4)'이 데이터베이스 형식이 문제가 될 것인가? 이제는'DECIMAL (19,4)'의 필요성과 관련하여 새로운 질문이 제기 될 것입니다. – ryvantage

+1

실제로 필연적 인 경우에는 반올림이 필요 없다고 가정하는 것을 싫어할 것입니다. 특히'HALF_UP' 솔루션이 작동하는 경우. – ryvantage

+0

내 경우 { "JPY", 15000.0f} 돈이 ArithmeticException을 던지고있었습니다. roundingMode에 의해 수정 됨 –

관련 문제