将String转换为Long时Scala NumberFormatException?

时间:2012-02-11 08:34:49

标签: java scala playframework

我们的应用程序是基于Scala并基于Play构建!框架。我使用Scala Random生成了一个随机数。这是用作我们应用中每个帐户的唯一键。

但是,当我将新帐户保存到数据库中时,会抛出java.lang.NumberFormatException

更多信息:我正在将帐户ID的字符串转换为Scala Long。我正在查找使用Squeryl对象,抓取ID,然后转换它。这是它的样子:

val account_id = Account.findAccountByUnique(account.uniqueKey).id.toLong

这就是findAccountByUnique的样子:

def findAccountByUnique(criteria: String) = {
    from(DB.accounts)(a =>
      where(a.uniqueKey == criteria)
        select (a))
  }

错误的堆栈跟踪:

java.lang.NumberFormatException: For input string: "468b68c"
        at java.lang.NumberFormatException.forInputString(Unknown Source)
        at java.lang.Long.parseLong(Unknown Source)
        at java.lang.Long.parseLong(Unknown Source)
        at scala.collection.immutable.StringLike$class.toLong(StringLike.scala:209)
        at scala.collection.immutable.StringOps.toLong(StringOps.scala:31)
        at controllers.Accounts$.save(Accounts.scala:44)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:548)
        at play.mvc.ActionInvoker.invoke(ActionInvoker.java:502)
        at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:496)
        at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:473)
        at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)
        at play.server.PlayHandler$NettyInvocation.execute(PlayHandler.java:257)
        at play.Invoker$Invocation.run(Invoker.java:278)
        at play.server.PlayHandler$NettyInvocation.run(PlayHandler.java:235)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

我将唯一键作为Scala LongString进行了类型转换,但它会抛出相同的错误。有任何关于修复的想法吗?

3 个答案:

答案 0 :(得分:5)

要将十六进制数转换为十进制数,请java.lang.Long.parseLong

scala> import java.lang.{ Long => JLong }
import java.lang.{Long=>JLong}

scala> JLong.parseLong("468b68c", 16)
res8: Long = 73971340

将十六进制转换为十进制的另一种方法是编写自己的方法:

def toHex(s: String): Long = {
  val Hex = "([0-9a-fA-F]+)".r
  s match {
    case Hex(_) => java.lang.Long.parseLong(s, 16)
    case _ => throw new NumberFormatException("invalid hex number: " + s)
  }
}

答案 1 :(得分:0)

Id为十六进制,因此您需要

val account_id = Account.findAccountByUnique(account.uniqueKey).id.toLong(16)

答案 2 :(得分:0)

经过进一步调查后,看起来有一个数据库助手返回垃圾数据。基本上它实际上是返回自己的“样本”数据,恰好是十六进制数据。它是Squeryl中的一个lib,看起来某些地方出现了错误,因此引发了“样本”响应。

看起来因为account.uniqueKey已经从之前的查询更新过,所以它带来了一些垃圾。还在调查它是如何发生的,但至少我发现了真正的问题。