2015-11-12 24 views
0

油滑2.1 斯卡拉2.11.7斯利克 - 龍的到的java.sql.Timestamp

隱式轉換無法獲取隱式轉換爲長< - >的java.sql.Timestamp或java.sql.Date工作。我有他們的工作對於其他轉換,如JodaTime.DateTime < - > java.sql.Timestamp中......

例如,在查詢返回的錯誤:

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 

這些都是implicits,他們是絕對正確導入在範圍:

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 
) 

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 
) 

我也使用java.lang.Long中,而不是試圖10

我在這裏錯過了什麼?謝謝!

-

附加信息:

查詢方法被定義爲(排隊是一個的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] 
} 
} 

表定義:

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

問題不在於你的映射,而在於你的查詢 - 你能告訴我們你是如何生成查詢的嗎? (Long正在被綁定,沒有被轉換爲Timestamp,導致錯誤)。或者,您的暗示有可能被Slick的默認暗示遮蔽。 –

+0

謝謝你的採訪。我添加了表格定義和查詢示例。這感覺就像你的第二個想法,Slick的默認含義被忽略了,而我的被忽略了。不知道如何解決它。 – user1661898

回答

0

您的問題在於Postgres中的底層queued列不是一個bigint但是一個timestamp with time zone。但是,在您的Slick的Jobs表定義中,您說該列是Long。 Slick已經知道如何將Long綁定到查詢,因此它永遠不會嘗試使用隱式將Long轉換爲另一個它確實知道如何綁定的類型。

理想情況下,你會只用一個sql.Timestamp爲您Jobs.queued列型(這是您的查詢片段您的評論似乎什麼來表示你認爲這是):

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

或者,你可以創建一個對於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 

最後,你可以添加一個自動投給你的Postgres數據庫轉換。

+0

謝謝肖恩。我天真地認爲我的隱式會被使用,因爲Slick沒有Long <->時間戳綁定。是否有一種解決方案,可以在不涉及數據庫功能或特性的情況下在Slick端執行Long <->時間戳轉換?我後來在我的模型中使用了ZonedDateTime,並且使用了隱式,但是這仍然給我帶來了麻煩。 – user1661898

+0

問題是,你告訴Slick該列是一個'Long' - Slick沒有根據實際表的模式檢查你的模式,所以它很樂意將'getMillis'中的'Long'綁定到查詢,導致* Postgres *拋出錯誤。如果你從'def queued = column [Long]'更改爲'def queued = column [Timestamp]',那麼在編譯時你會在'getJobs'方法中得到不同的錯誤*,然後你可以解決這個錯誤。 –

+0

如果使用列[Timestamp],但Long保持JobRow類,將通過Long <-> Timestamp之間的隱式轉換工作?或者我需要在def * = ...行中定義一個自定義轉換? – user1661898