2012-02-11 5 views
1

Наше приложение Scala основано и построено на Play! фреймворк. Я создал случайное число, используя Scala Random. Это нужно использовать как уникальный ключ для каждой учетной записи в нашем приложении.Scala NumberFormatException при преобразовании строки в Long?

Однако, когда я иду, чтобы сохранить новую учетную запись в базу данных, он бросает java.lang.NumberFormatException:

Дополнительной информации: Я преобразование строки с идентификатором аккаунта в Scala Лонг. Я просматриваю его с помощью объекта Squeryl, захватывая идентификатор, а затем преобразую его. Вот как это выглядит:

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) 

Я typecasted уникальный ключ, как Scala Long, так и String, но он вызывает ту же ошибку. Любая идея относительно исправления?

+0

Если вы получаете серию случайных чисел, они не обязательно будут уникальными. Чтобы лучше помочь, опубликуйте [SSCCE] (http://sscce.org/). –

+0

Дополнительная информация Вам нужна дополнительная информация? С вашего комментария, я даже попробовал его с java.UUID (очень уникальный), и он бросает ту же ошибку. – crockpotveggies

+0

* «Какая еще информация вам нужна?» * В какой части S-S-C-C-E у вас возникли проблемы с пониманием? –

ответ

0

После дальнейшего расследования похоже, что помощник базы данных, возвращающий нежелательные данные. По сути, он фактически возвращал свои собственные «образцовые» данные, которые оказались шестнадцатеричными. Это был lib в Squeryl, похоже, что что-то исказилось где-то, и поэтому оно вызвало «образец» ответа.

Похоже, что account.uniqueKey был обновлен с помощью предыдущего запроса, это принесло с собой некоторые нежелательные эффекты. Все еще исследуя, как это произошло, но по крайней мере я нашел настоящую проблему.

0

Id в шестнадцатеричном, так что вам нужно

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

К сожалению, это вызвало ошибку компилятора. Но я думаю, что происходит волшебство Scala. 'Scala.this.Predef.augmentString (org.squeryl.PrimitiveTypeMode.singleColumnQuery2RightHandSideOfIn [models.Account] (models.Account.findAccountByUnique (account.uniqueCode)). Идентификатор).toLong типа Long не принимает параметры – crockpotveggies

+0

Причина, по которой я говорю, магия, если я удалю всю эту строку, вдруг у меня есть доступ к правильному идентификатору учетной записи, когда я обращаюсь к account.id. Это должен быть «супер объект» Squeryl, который что-то делает где-то, потому что нет логического кода, просматривающего ключ в объекте учетной записи. – crockpotveggies

+0

Я экстраполировал это, так как toLong, вероятно, использует parseLong() java, там будет существовать toLong (int base). Извините –

4

Чтобы преобразовать шестнадцатеричное число в десятичное один есть 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) 
    } 
} 
+0

Похоже, это будет трюк, моя единственная забота - почему возвращается шестнадцатеричный? Это тестовая БД, где максимальный ID равен 14. Спасибо! – crockpotveggies

+0

@DeLonge: Вы попросили способ преобразования строки в шестнадцатеричное число, и я показал вам путь. Если у вас есть дополнительные требования, вы должны сказать им. – sschaef

+0

Это было не так. Это был ответ Джопа, в котором указывалась шестнадцатеричная проблема. Проблемы всегда развиваются, и если вы больше не можете комментировать, пожалуйста, любезно скажите это. – crockpotveggies

Смежные вопросы