Search code examples
scalascalaquery

How is this a "type mismatch"?


found   : (Int, String, Option[java.lang.String])
required: (Int, String, Option[java.lang.String])

Pertinent code:

object M extends Table[(Int, String, Option[String])]("table") {

  def msaid = column[Int]("msaid", O NotNull)
  def name = column[String]("name", O DBType "varchar(255)")
  def shape = column[Option[String]]("shape")
  def * = msaid ~ name ~ shape

  type T = (Int, String, Option[java.lang.String])

  def apply(msa: T) = 1

  def q() = db withSession { s: Session => (for (r <- M) yield M(*)).list()(s) }
                                                                 ^
                                                                 ^
...

I've also tried

  type T = (Int, String, Option[String])

The ultimate goal is that I want all the selected columns to converted into an Object with named accessors, instead of being a tuple.

Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_07).

UPDATE:

Here's a Gist of the issue (slightly simplified from the above code and eliminates any String/java.lang.String "confusion" by using only Int.)


Solution

  • The error message didn't use to tell you which was the TupleN, though I think that was improved at some point. The mismatch is between a tuple and n args. Or not.

    The fix is in 2.9.2. I notice your .sbt uses 2.9.1 scalaquery, in case that matters. And isn't scala-tools.org obsolete? Sorry for half-helping.

    Speaking as a non-user, it looks like a Projection2 is not the Tuple you seek, albeit a Product:

    class Projection2 [T1, T2] extends (Column[T1], Column[T2]) with Projection[(T1, T2)] 
    

    REPLing:

    scala> M.column[Int]("id") ~ M.column[Int]("n")
    res1: (Int, Int) = Projection2
    
    scala> M(res1)
    <console>:23: error: type mismatch;
     found   : (Int, Int)
     required: (Int, Int)
                  M(res1)
                    ^
    
    scala> M.apply
                                    def apply(v: (Int, Int)): Int   
    
    scala> M.apply((1,2))
    res3: Int = 1