Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create custom column mapping for java.time.LocalDate with Slick

I'm using Slick 3.1.0-M2 and I wish to use the java.time.LocalDate and java.time.LocalTime in my tables. I do it like this:

import java.sql.{Date, Time, Timestamp}
import java.time.{LocalDate, LocalTime, LocalDateTime, ZoneOffset}

trait DateTimeColumns {

  import slick.driver.PostgresDriver.api._

  implicit val localDateTimeColumnType = MappedColumnType.base[LocalDateTime, Timestamp](
    d => Timestamp.from(d.toInstant(ZoneOffset.ofHours(0))),
    d => d.toLocalDateTime
  )

  implicit val dateColumnType = MappedColumnType.base[LocalDate, Date](
    d => Date.valueOf(d),
    d => d.toLocalDate
  )

  implicit val timeColumnType = MappedColumnType.base[LocalTime, Time](
    localTime => Time.valueOf(localTime),
    time => time.toLocalTime
  )
}

So I have 3 implicit mappings but only the first one compiles. The ones with java.sql.Date and java.sql.Time fails the compilation with:

could not find implicit value for evidence parameter of type slick.driver.PostgresDriver.BaseColumnType[java.sql.Date]

When I do a implicit parameter inspection in IntelliJ I can see that the first mapping finds TimestampJdbcType in the file JdbcTypesComponent.scala. Right next to that I see the TimeJdbcType and DateJdbcType. So how come the first one is found but the others aren't?

like image 813
Andreas Du Rietz Avatar asked Sep 07 '15 19:09

Andreas Du Rietz


1 Answers

If you check the slick.driver.JdbcTypesComponent, you will find a trait ImplicitColumnTypes contains lots of implicits for column type, including:

implicit def timeColumnType = columnTypes.timeJdbcType
implicit def dateColumnType = columnTypes.dateJdbcType

The latter two you defined actually have the same name with the default ones.

Changing the name of them or renaming the default ones when importing works for me.

import slick.driver.PostgresDriver.api._
import slick.driver.PostgresDriver.api.{ timeColumnType => DefaultTimeColumnType }

implicit val myDateColumnType = MappedColumnType.base[LocalDate, Date](
    ld => Date.valueOf(ld),
    d => d.toLocalDate
)

implicit val timeColumnType = MappedColumnType.base[LocalTime, Time](
    localTime => Time.valueOf(localTime),
    time => time.toLocalTime
)
like image 109
Allen Chou Avatar answered Sep 19 '22 10:09

Allen Chou