How to convert from a Scala BigDecimal to Java BigDecimal

Scala FAQ: How do I convert from a Scala BigDecimal instance to a Java BigDecimal?

Call the bigDecimal method on your Scala BigDecimal instance, as shown in this example in the REPL:

scala> val sb = scala.math.BigDecimal(12345)
sb: scala.math.BigDecimal = 12345

scala> val jb = sb.bigDecimal
jb: java.math.BigDecimal = 12345

As you can see, invoking sb.bigDecimal returns a java.math.BigDecimal.

Converting from a Scala BigDecimal to a Java BigDecimal works like this:

scala> val sb2 = BigDecimal(jb)
sb2: scala.math.BigDecimal = 12345

Discussion

I’ve found that this is an important conversion process to know when working with a MySQL DECIMAL field, which you’ll want to use when handling money/currency. The Java MySQL driver expects and returns a java.math.BigDecimal type, so you need to know the Scala to Java conversion to insert a Scala BigDecimal field into a database, as in this method:

/**
* This method returns the value of the auto_increment field when the transaction is inserted
* into the database table.
*
* Note: Inserting `transaction.price` does not work, throws nasty exception; need to insert a Java BigDecimal.
*/
def insert(transaction: Transaction): Option[Long] = {
val id: Option[Long] = DB.withConnection { implicit c =>
  SQL("insert into transactions (symbol, ttype, price, quantity, notes) values ({symbol}, {ttype}, {price}, {quantity}, {notes})")
    .on("symbol" -> transaction.symbol.toUpperCase,
        "ttype" -> transaction.ttype,
        "price" -> transaction.price.bigDecimal,  //converts to java.math.BigDecimal
        "quantity" -> transaction.quantity,
        "notes" -> transaction.notes
    ).executeInsert()
  }
id
}

If you attempt to insert the price field into MySQL without first converting the object from a Scala BigDecimal to a Java BigDecimal, you’ll get an exception that looks like this:

[error] play - Cannot invoke the action, eventually got an error: java.lang.ClassCastException:
scala.math.BigDecimal cannot be cast to java.math.BigDecimal
[error] application - ! @6hl56h2la - Internal server error, for (POST) [/transactions/add] ->
play.api.Application$$anon$1: Execution exception[[
ClassCastException: scala.math.BigDecimal cannot be cast to java.math.BigDecimal]]

You may also see error messages like these:

[error] c.j.b.ConnectionHandle - Database access problem. Killing off this connection and all remaining connections in the connection pool. SQL State = HY000
[error] play - Cannot invoke the action, eventually got an error: java.sql.SQLException: Incorrect decimal value: '\xAC\xED\x00\x05sr\x00\x15scala.math.BigDecimalq\xBA\x14\xC4\xF8\xF1O\x1A\x02\x00\x02L\x00\x0AbigDecimalt\x00\x16Ljava/math/BigD' for column 'price' at row 1
[error] application -

Add new comment

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.