0
votes

I'm having some trouble doing a Plain SQL Query using String Interpolation. I'm trying to query a MS-SQL 2008 database using Microsofts sqljdbc4.jar.

The table is simple:

[serv_num]
number (nvarchar(15))  |  name (nvarchar(50))
=============================================
    1234               |     AA
    +345               |     BB

The code I'm using is as follows:

import java.sql.{Connection, DriverManager}
import org.slf4j.LoggerFactory
import scala.collection.JavaConversions._
import scala.slick.session.Database
import Database.threadLocalSession
import scala.slick.jdbc.{GetResult, StaticQuery => Q}
import Q.interpolation

object NumImport extends App {
    def logger = LoggerFactory.getLogger("NumImport")
    implicit val getServNumResult = GetResult(r => ServNum(r.<<, r.<<))

    override def main(args: Array[String]) {
        val uri = "jdbc:sqlserver://192.168.1.2;databaseName=slicktestdb;user=yyyy;password=xxxxxx"
        val drv = "com.microsoft.sqlserver.jdbc.SQLServerDriver"

        Database.forURL(uri, driver = drv) withSession {
           def getServNum(n: String) = sql"select number, name from serv_num where number = $n".as[ServNum]
           val result = getServNum("1234")
           println(result.firstOption)
        }
    }

    case class ServNum(num: String, name: String)
}

My issue is that I'm getting a java.lang.NullPointerException on result.firstOption (I think!). This happens when a row is found. If try to select a number that doesn't exist, say getServNum("34"), then result.firstOption is a None, as expected.

Stacktrace:

08:54:47.932 TKD [run-main] DEBUG scala.slick.session.BaseSession - Preparing statement: select number, name from serv_num where number = ?
[error] (run-main) java.lang.NullPointerException
java.lang.NullPointerException
at scala.slick.jdbc.StaticQuery.extractValue(StaticQuery.scala:16)
at scala.slick.jdbc.StatementInvoker$$anon$1.extractValue(StatementInvoker.scala:37)
at scala.slick.session.PositionedResultIterator.foreach(PositionedResult.scala:212)
at scala.slick.jdbc.Invoker$class.foreach(Invoker.scala:91)
at scala.slick.jdbc.StatementInvoker.foreach(StatementInvoker.scala:10)
at scala.slick.jdbc.Invoker$class.firstOption(Invoker.scala:41)
at scala.slick.jdbc.StatementInvoker.firstOption(StatementInvoker.scala:10)
at scala.slick.jdbc.UnitInvoker$class.firstOption(Invoker.scala:148)
at scala.slick.jdbc.StaticQuery0.firstOption(StaticQuery.scala:95)

I tried debugging and following the stacktrace, but I'm quite new to both Scala and Slick, so I'm lost. If anyone could help me or point me in the right direction I would appreciate it a lot.

Thanks.

1
Are either of the columns selected in that row that is failing null and/or do they allow nulls? - cmbaxter
None of them allow nulls. - Franz
Would you mind trying to switch both of your case class fields to Option[String instead of String and try again? - cmbaxter
I got the same NullPointerException when switching the case class fields to Option[String]. - Franz
I think I know what it is. I'll put here as comment. If it works, let me know and I will add as an answer. Move your case class definition outside of the object, so it's not tied to it the way it is now. - cmbaxter

1 Answers

1
votes

In looking at the slick source code where the exception was happening, I could see that it was trying to invoke apply on the GetResult object, but that object seemed to be null. In thinking about what might of caused it, I'm suggesting that you move the implicit inside of the main method. It seems that the way things are structured, slick is losing track of the implicit ResultSet to case class converter (the GetResult)