Question

I'm running into a compatibility problem under Scala while using Slick and Play. I'm attempting to use the Date type in one of my model schema via Slick, and then make that date available in a form in Play:

Model:

case class Test(id: Int, date: java.sql.Date)
class Tests(tag: Tag) extends Table[Test](tag, "Tests") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def date = column[java.sql.Date]("date")
  def * = (id, date) <> (Test.tupled, Test.unapply)
}

Controller form element:

def testForm: Form[Test] = {
  Form(
  mapping(
    "id" -> number,
    "date" -> date)(Test.apply)(Test.unapply)))
}

However, the form has a compilation error, because Slick uses java.sql.Date, while Play uses java.util.Date:

"type mismatch; found : (Int, java.sql.Date) => models.Test required: (Int,  java.util.Date) => ?"

Is there any built-in support that Slick or Play provides for proper interoperability, or do you have to manually convert between them? How/where would this best be done?

Was it helpful?

Solution

Play supports java.sql.Date, you just need to do the mapping as

def testForm: Form[Test] = {
    Form(
    mapping(
        "id" -> number,
        "date" -> sqlDate)(Test.apply)(Test.unapply)))
}

Note that I haven't tested it, but the docs show that sqlDate exists.

Another option would be to define a type mapping between java.util.Date and java.sql.Date in slick. Look here to see how.

Also, if you haven't yet, look at joda time or some scala wrapper. It will probably make working with dates and times easier.

OTHER TIPS

You can use jodaDate mapping in the form. Also use joda DateTime in the model as well as table column and define an implicit joda to sql mapper.

def testForm: Form[Test] = {
  Form(
    mapping(
      "id" -> number,
       "date" -> jodaDate)(Test.apply)(Test.unapply)
  )

import org.joda.time.DateTime
import java.sql.Timestamp
import play.api.db.slick.Config.driver.simple._  // I suppose you are using play-slick (https://github.com/freekh/play-slick) plugin


object JodaToSqlMapper {
  implicit val dateTimeToDate = MappedColumnType.base[DateTime, Timestamp](
    dateTime => new Timestamp(dateTime.getMillis),
    timestamp => new DateTime(timestamp))
}

case class Test(id: Int, date: org.joda.time.DateTime)

import JodaToSqlMapper._

class Tests(tag: Tag) extends Table[Test](tag, "Tests") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def date = column[DateTime]("date")
  def * = (id, date) <> (Test.tupled, Test.unapply _)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top