Slick 2.0 Map a java.util.Date in a Table
Asked Answered
C

1

5

I use slick 2.0 and I have a simple case class :

case class Message(id: Option[Long], userId: Option[Long], body:String, creationDate:Date)

And the following mapping :

class Messages(tag: Tag) extends Table[Message](tag, "message") {
  import Mapping.Mapper._

  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def userId = column[Long]("user_id")
  def body = column[String]("body")
  def creationDate = column[java.util.Date]("creationDate")
  def * = (id.?, userId.?, body, creationDate) <> (Message.tupled, Message.unapply _)
}

I import this implicit mapper :

implicit def date2sqlDate(d: java.util.Date): java.sql.Date = new java.sql.Date(d.getTime())

I keep getting this error:

No matching Shape found. Slick does not know how to map the given types.
Possible causes: T in Table[T] does not match your * projection. 
Or you use an unsupported type in a Query (e.g. scala List).
Required level: 
scala.slick.lifted.ShapeLevel.Flat Source type:
(scala.slick.lifted.Column[Option[Long]], 
scala.slick.lifted.Column[Option[Long]], 
scala.slick.lifted.Column[String], 
scala.slick.lifted.Column[java.sql.Date]) 
Unpacked type: (Option[Long], Option[Long], String, java.util.Date)
Packed type: Any

How can I use a java.util.Date in my table ? I don't want to use JodaTime or everything else, I want just plain old java.util.Date.

it looks like we need to use MappedColumnType http://slick.typesafe.com/doc/2.0.1/userdefined.html#scalar-types

but a simple mapping like this one doesn't work

implicit val date2sqlDateMapper = JdbcDriver.MappedJdbcType.base[java.util.Date, java.sql.Date](
      { d => date2sqlDate(d) }, 
      { sqlDate => sqlDate } 
      )

I'll get could not find implicit value for evidence parameter of type scala.slick.driver.JdbcDriver.BaseColumnType[java.sql.Date]

Corbicula answered 8/5, 2014 at 14:27 Comment(0)
I
11
  implicit val JavaUtilDateMapper =
    MappedColumnType .base[java.util.Date, java.sql.Timestamp] (
      d => new java.sql.Timestamp(d.getTime),
      d => new java.util.Date(d.getTime))

You need to have something like this in your implicit scope, And as you have noticed, java.util.Date is mapped to java.sql.Timestamp, if you map to java.sql.Date, it will lose time part

Illusionism answered 9/5, 2014 at 2:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.