Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slick 2.0 Map a java.util.Date in a Table

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]

like image 769
ACO Avatar asked May 08 '14 14:05

ACO


1 Answers

  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

like image 93
jilen Avatar answered Oct 23 '22 09:10

jilen