简体   繁体   中英

Slick - implicit conversion of Long to java.sql.Timestamp

Slick 2.1 Scala 2.11.7

Cannot get implicit conversions for Long <-> java.sql.Timestamp or java.sql.Date working. I have them working for other conversions, such as JodaTime.DateTime <-> java.sql.Timestamp...

For example, error returned on query:

org.postgresql.util.PSQLException: ERROR: operator does not exist: 
timestamp with time zone >= bigint Hint: No operator matches 
the given name and argument type(s). You might need to add explicit type casts. 
Position: 325

These are the implicits and they are definitely imported properly to be in scope:

implicit val LongToTimestamp = MappedColumnType.base[Long, Timestamp](
longTS => new Timestamp(longTS),
sqlTS => sqlTS.getTime
)

implicit val LongToDate = MappedColumnType.base[Long, java.sql.Date](
longTS => new java.sql.Date(longTS),
sqlDate => sqlDate.getTime
)

I have also tried using java.lang.Long instead:

implicit val LongToTimestamp = MappedColumnType.base[java.lang.Long, Timestamp](
longTS => new Timestamp(longTS),
sqlTS => sqlTS.getTime
)

implicit val LongToDate = MappedColumnType.base[java.lang.Long, java.sql.Date](
longTS => new java.sql.Date(longTS),
sqlDate => sqlDate.getTime
)

What am I missing here? Thank you!

--

additional info:

The query method is defined as (queued is a java.sql.Timestamp) :

def getJobs(jobTypeId: Short, onOrAfter: DateTime): Seq[JobRow] = {
 val q1 = for{j <- Jobs if j.jobTypeId === jobTypeId && j.queued >= onOrAfter.getMillis} yield j
 db.withSession{ implicit s =>
   q1.buildColl[Seq]
 }
}

The table definition:

class Jobs(tag: Tag) extends Table[JobRow](tag, "job") {

def jobId = column[Long]("job_id", O.PrimaryKey, O.NotNull)

def jobTypeId = column[Short]("job_type_id", O.NotNull)

def queued = column[Long]("queued", O.NotNull)

def * = (jobId, jobTypeId, queued) <>((JobRow.apply _).tupled, JobRow.unapply_ )

def pk = primaryKey("job_pk", jobId)
}

Your problem here is that the underlying queued column in Postgres is not a bigint but a timestamp with time zone . However, in your Jobs table definition for Slick you say that the column is a Long . Slick already knows how to bind a Long to a query, so it never tries to use your implicit to convert the Long into another type that it does know how to bind.

Ideally you would just use a sql.Timestamp as your Jobs.queued column type (which is what your comment on your query snippet seems to indicate you think it is):

def queued = column[Timestamp]("queued", O.NotNull)
// As opposed to your example where this is
// def queued = column[Long]("queued", O.NotNull)

Or, you can create a Slick wrapper for the to_timestamp(double) :

val toTimestamp = SimpleFunction.unary[Double, Timestamp]("to_timestamp")
val q1 = for {
  j <- Jobs
  if j.jobTypeId === jobTypeId && j.queued >= toTimestamp(onOrAfter.getMillis)
} yield j

Finally, you can add an automatic cast to your Postgres DB to convert.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM