filter by UUID: JdbcSQLException: Hexadecimal string contains non-hex character: "b3820e49-e666-...

2,284 views
Skip to first unread message

mkranz

unread,
Apr 11, 2017, 9:58:53 AM4/11/17
to Slick / ScalaQuery
hello everybody

i'm currently in the process of migrating an old scala/play project from play 2.3 to 2.5.
i also move from play-slick 0.8.1 to 2.1.0, so it's quite a change.

i'm doing ok so far, but now i'm having a serious issue with one of the queries.
the query in question is a simple filter by UUID that worked just fine before the migration, so i guess i messed something up on the way, but i just can't figure it out.
when i remove the filter part from the query it works, so it seems to be all about the UUID.

it's also irritating because inserting works without a problem.

so, if someone has an idea what could cause this problem, please let me know.

thanks in advance

mkranz


filter query exception

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[JdbcSQLException: Hexadecimal string contains non-hex character: "d4b87ccd-0aa5-4b79-aa69-5d8648b32410"; SQL statement:


select "ID", "UUID", "VERSION", "ADMIN_TOKEN", "CREATION_DATE", "MODIFICATION_DATE", "ID_ADOPTION_SCAN_EVENT", "OWNER", "OWNER_EMAIL", "TITLE", "MESSAGE_PRIV", "MESSAGE_PUB", "NOTIFY_SCANS", "NOTIFY_POSTS" from "QRTAG" where "UUID" = 'd4b87ccd-0aa5-4b79-aa69-5d8648b32410' order by "VERSION" desc [90004-194]]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:293)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:220)
at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
at global.Global$.onError(Global.scala:20)
at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:346)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:345)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:70)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:40)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:248)
at scala.concurrent.Promise$class.complete(Promise.scala:55)
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:153)
at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:251)
at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:251)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
at akka.dispatch.BatchingExecutor$BlockableBatch$$anonfun$run$1.apply$mcV$sp(BatchingExecutor.scala:91)
at akka.dispatch.BatchingExecutor$BlockableBatch$$anonfun$run$1.apply(BatchingExecutor.scala:91)
at akka.dispatch.BatchingExecutor$BlockableBatch$$anonfun$run$1.apply(BatchingExecutor.scala:91)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:72)
at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:90)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:39)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:415)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: org.h2.jdbc.JdbcSQLException: Hexadecimal string contains non-hex character: "d4b87ccd-0aa5-4b79-aa69-5d8648b32410"; SQL statement:
select "ID", "UUID", "VERSION", "ADMIN_TOKEN", "CREATION_DATE", "MODIFICATION_DATE", "ID_ADOPTION_SCAN_EVENT", "OWNER", "OWNER_EMAIL", "TITLE", "MESSAGE_PRIV", "MESSAGE_PUB", "NOTIFY_SCANS", "NOTIFY_POSTS" from "QRTAG" where "UUID" = 'd4b87ccd-0aa5-4b79-aa69-5d8648b32410' order by "VERSION" desc [90004-194]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.util.StringUtils.convertHexToBytes(StringUtils.java:946)
at org.h2.value.Value.convertTo(Value.java:938)
at org.h2.expression.Comparison.optimize(Comparison.java:204)
at org.h2.command.dml.Select.prepare(Select.java:856)
at org.h2.command.Parser.prepareCommand(Parser.java:261)
at org.h2.engine.Session.prepareLocal(Session.java:564)
at org.h2.engine.Session.prepareCommand(Session.java:505)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1204)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:73)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:310)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
at slick.jdbc.JdbcBackend$SessionDef$class.prepareStatement(JdbcBackend.scala:322)
at slick.jdbc.JdbcBackend$BaseSession.prepareStatement(JdbcBackend.scala:434)
at slick.jdbc.StatementInvoker.results(StatementInvoker.scala:33)
at slick.jdbc.StatementInvoker.iteratorTo(StatementInvoker.scala:22)
at slick.jdbc.Invoker$class.foreach(Invoker.scala:48)
at slick.jdbc.StatementInvoker.foreach(StatementInvoker.scala:16)
at slick.jdbc.Invoker$class.firstOption(Invoker.scala:24)
at slick.jdbc.StatementInvoker.firstOption(StatementInvoker.scala:16)
at slick.jdbc.StreamingInvokerAction$HeadOptionAction.run(StreamingInvokerAction.scala:57)
at slick.jdbc.StreamingInvokerAction$HeadOptionAction.run(StreamingInvokerAction.scala:56)
at slick.basic.BasicBackend$DatabaseDef$$anon$2.liftedTree1$1(BasicBackend.scala:240)
at slick.basic.BasicBackend$DatabaseDef$$anon$2.run(BasicBackend.scala:240)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)


part of the code below (query in question in bold)

import java.util.Date
import java.util.UUID
import play.api.Logger
import play.api.libs.Crypto
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._
import play.api.libs.json._

import play.api.db.slick.HasDatabaseConfig
import slick.jdbc.JdbcProfile
import play.api.db.slick.{ HasDatabaseConfigProvider, DatabaseConfigProvider }
import play.api.Play
import javax.inject.{ Singleton, Inject }
import scala.concurrent.ExecutionContext
import controllers.util.DateConversion


case class QrTag(
  id
: Long,
  uuid
: UUID,
  version
: Long,
  adminToken
: String,
  created
: Date,
  modified
: Date,
  adoptionScanEventId
: Option[Long],
  owner
: Option[String],
  ownerEmail
: Option[String],
  title
: Option[String],
  messagePublic
: Option[String],
  messagePrivate
: Option[String],
  notifyScans
: Boolean,
  notifyPosts
: Boolean
)

trait
QrTagsTableComponent extends DateConversion { self: HasDatabaseConfigProvider[JdbcProfile] =>
 
import profile.api._
 
  val qrTagsTableQuery
= TableQuery[QrTagsTable]
 
 
class QrTagsTable(tag: Tag) extends Table[QrTag](tag, "QRTAG") {
 
   
def id = column[Long]("ID") // , O.NotNull
   
def uuid = column[UUID]("UUID") // , O.NotNull
   
def version = column[Long]("VERSION") // , O.NotNull
   
def adminToken = column[String]("ADMIN_TOKEN") // , O.NotNull
   
def created = column[Date]("CREATION_DATE") (localDateColumnType) // , O.NotNull
   
def modified = column[Date]("MODIFICATION_DATE") (localDateColumnType) // , O.NotNull
   
def adoptionScanEventId = column[Option[Long]]("ID_ADOPTION_SCAN_EVENT") // , O.Nullable
   
def owner = column[Option[String]]("OWNER") // , O.Nullable
   
def ownerEmail = column[Option[String]]("OWNER_EMAIL") // , O.Nullable
   
def title = column[Option[String]]("TITLE") // , O.Nullable
   
def messagePublic = column[Option[String]]("MESSAGE_PRIV")// , O.Nullable
   
def messagePrivate = column[Option[String]]("MESSAGE_PUB") // , O.Nullable
   
def notifyScans = column[Boolean]("NOTIFY_SCANS") // , O.NotNull
   
def notifyPosts = column[Boolean]("NOTIFY_POSTS") // , O.NotNull
   
def * = (id, uuid, version, adminToken, created, modified, adoptionScanEventId, owner, ownerEmail, title, messagePublic, messagePrivate, notifyScans, notifyPosts) <> (QrTag.tupled, QrTag.unapply)
   
def idx = index("idx_qrtag_id", id)
   
def idx_uuid = index("idx_qrtag_uuid", uuid)
   
def pk = primaryKey("pk_qrtag", (id, version))  
 
}
}

@Singleton()
class QrTagsDAO @Inject() (protected val dbConfigProvider: DatabaseConfigProvider) (implicit ec: ExecutionContext)
 
extends QrTagsTableComponent
 
with HasDatabaseConfigProvider[JdbcProfile]
 
with ScanEventsTableComponent
 
with GroupTagMapTableComponent{
 
 
import profile.api._  
 
  val logger
= Logger(getClass.getName.replace("$", ""))
 
 
def findByUuid(uuid: UUID) = {
    db
.run(qrTagsTableQuery.filter(_.uuid === uuid).sortBy{_.version.desc}.result.headOption)
 
}


 
private def insert(date: Date) = {
    val insertQrTag
= for{
      nextId
<- QrTagIdSequence.nextId
      incr
<- qrTagsTableQuery += QrTag(nextId, UUID.randomUUID(), version=0, Crypto.generateToken, date, date, None,       None, None, None, None, None, false, false)
      tag
<- findByIdAction(nextId)
   
} yield tag.get    
    insertQrTag
 
}
...
}


build.sbt


lazy val root = (project in file(".")).enablePlugins(PlayScala, SbtWeb)

scalaVersion
:= "2.11.8"

libraryDependencies
++= Seq(
  filters
,
  cache
,
  ws
,
  specs2
% Test,
 
"net.glxn" % "qrgen" % "1.4" withJavadoc(),
 
"com.typesafe.play" %% "play-slick" % "2.1.0",
 
"com.typesafe.play" %% "play-slick-evolutions" % "2.1.0",
 
"com.h2database" % "h2" % "1.4.194",
 
"nu.validator.htmlparser" % "htmlparser" % "1.2.1",
 
"org.scalatestplus.play" %% "scalatestplus-play" % "1.5.0" % "test",
 
"org.webjars" %% "webjars-play" % "2.4.0-2",
 
"org.webjars" % "jquery" % "3.0.0",
 
"org.webjars" % "bootstrap" % "3.3.2" exclude("org.webjars", "jquery"),
 
"org.webjars" % "bootstrap-switch" % "3.3.2" exclude("org.webjars", "jquery"),
 
"org.webjars" % "angularjs" % "1.5.7" exclude("org.webjars", "jquery"),
 
"org.webjars.bower" % "angular-route" % "1.5.7" exclude("org.webjars", "angularjs"),
 
"org.webjars" % "angular-ui-bootstrap" % "0.12.0" exclude("org.webjars", "jquery"),
 
"org.webjars" % "angular-translate" % "2.6.0",
 
"org.webjars" % "angular-translate-loader-static-files" % "2.4.0" exclude("org.webjars", "angular-translate"),
 
"org.webjars" % "angular-google-maps" % "2.0.11" exclude("org.webjars", "jquery"),
 
"org.webjars.bower" % "angular-animate" % "1.5.7" exclude("org.webjars", "angularjs"),
 
"org.webjars.bower" % "angular-touch" % "1.5.7" exclude("org.webjars", "angularjs")
)

routesGenerator
:= InjectedRoutesGenerator

resolvers
+= "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases"

pipelineStages
:= Seq(rjs, digest, gzip)

fork
in run := true


mkranz

unread,
Apr 12, 2017, 10:49:00 AM4/12/17
to Slick / ScalaQuery
just for the record, problem solved.

turned out, for some reason the old evolution schema generated by slick had the uuid column as type OTHER instead of UUID.

cheers

mkranz
Reply all
Reply to author
Forward
0 new messages