Andy
Andy

Reputation: 221

Joda-Date Mapper for Slick - MappedColumnTyoe

My problem is very close to this question, but my error is different.

Customer Type Mapper for Slick SQL

This is my utility class where JDATE and the Mapper is defined

package org.mydomain.utils
import slick.driver.MySQLDriver.simple._
import org.joda.time.DateTime
import java.sql.Date
import org.joda.time.DateTime
import java.sql.Timestamp

sealed trait JDATE

object DateUtils {

  implicit def jdateColumnType  =
      MappedColumnType.base[DateTime, Timestamp](
        dt => new Timestamp(dt.getMillis),
        ts => new DateTime(ts.getTime)
  )
}

The domain object User.scala is as follows

case class UserRow(id: Long, birthday: JDATE)

class User(tag: Tag) extends Table[UserRow](tag, "USER") {
def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
def birthday = column[JDATE]("BIRTHDAY")

def * = (id, birthday) <> (UserRow.tupled, UserRow.unapply)
}

Error: not enough arguments for method column: (implicit tm: scala.slick.ast.TypedType[org.mydomain.utils.JDATE])scala.slick.lifted.Column[org.mydomain.utils.JDATE]. Unspecified value parameter tm.

How to pass the tm here ? Apologies for this noob question. Thanks

Upvotes: 0

Views: 2069

Answers (1)

Sean Vieira
Sean Vieira

Reputation: 159995

There are two problems here:

  1. You don't need JDATE - you don't actually want to use it anywhere, what you want is to be able to translate between DateTime and Timestamp instances. Use DateTime for the column type instead (e. g. column[DateTime]("BIRTHDAY") rather than column[JDATE]("BIRTHDAY"))
  2. You never actually import your implicit DateTime <> Timestamp converter, so it is never picked up by Slick's column. Either:

    // Import the implicit in the constructor
    class User(tag: Tag) extends Table[UserRow](tag, "USER") {
      import org.mydomain.utils.DateUtils.jdateColumnType
      // Your code here
    }
    

    or

    // Explicitly pass the implicit converter in yourself
    class User(tag: Tag) extends Table[UserRow](tag, "USER") {
      // ... snip ...
      def birthday = column[DateTime]("BIRTHDAY")(DateUtils.jdateColumnType)
      // ... snip ...
    }
    

    or (best option), create your own driver by extending the MySql driver with your custom implicit in a trait:

    package org.mydomain.db
    
    import scala.slick.driver.{MySqlDriver, JdbcDriver}
    
    trait DateUtils {
      implicit def jdateColumnType  =
          MappedColumnType.base[DateTime, Timestamp](
            dt => new Timestamp(dt.getMillis),
            ts => new DateTime(ts.getTime)
      )
    }
    
    trait CustomMySqlDriver extends JdbcDriver with MySqlDriver with DateUtils
    
    object CustomMySqlDriver extends CustomMySqlDriver
    

    and you can then use it like this:

    import org.mydomain.db.CustomMySqlDriver.simple._
    
    class User(tag: Tag) extends Table[UserRow](tag, "USER") {
      // ... snip ...
      def birthday = column[DateTime]("BIRTHDAY")
      // ... snip ...
    }
    

Upvotes: 2

Related Questions