Создайте пользовательское сопоставление столбцов для java.time.LocalDate с Slick

Я использую Slick 3.1.0-M2, и я хочу использовать java.time.LocalDate и java.time.LocalTime в моих таблицах. Я делаю это так:

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
  )
}

Итак, у меня есть 3 неявных отображения, но компилируется только первое. Те, у которых есть java.sql.Date и java.sql.Time, не компилируются:

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

Когда я делаю неявную проверку параметров в IntelliJ, я вижу, что первое сопоставление находит TimestampJdbcType в файле JdbcTypesComponent.scala. Прямо рядом с этим я вижу TimeJdbcType и DateJdbcType. Так почему же первый найден, а другие нет?

1 ответ

Решение

Если вы проверите slick.driver.JdbcTypesComponent, вы найдете trait ImplicitColumnTypes содержит много последствий для типа столбца, в том числе:

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

Последние два, которые вы определили, на самом деле имеют то же имя, что и имена по умолчанию.

Изменение их имен или переименование по умолчанию при импорте работает для меня.

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
)
Другие вопросы по тегам