Slick使っていて嵌ったのでメモ
import slick.driver.MySQLDriver.api._
import java.sql.Timestamp
case class Hoge(
id : Long,
t1 : Timestamp,
t2 : Timestamp
)
class HogeTable(tag: Tag) extends Table[Hoge](tag, "Hoge"){
def id = column[Long]("id",O.PrimaryKey, O.AutoInc)
def t1 = column[Timestamp]("t1")
def t2 = column[Timestamp]("t2")
def * = (id, t1, t2) <> (Hoge.tupled, Hoge.unapply)
}
のような2つ以上のTimestampフィールドを持つテーブルを定義した場合、schemaで自動生成されるSQL文が
create table `Hoge` (`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,`t1` TIMESTAMP NOT NULL,`t2` TIMESTAMP NOT NULL)
のようになります。
しかし、MySQLでは、デフォルトの設定では、MySQLのドキュメントに書いているように、TIMESTAMPを2つ以上同じテーブルに持つことが出来ません。この問題を解決するには、TIMESTAMPのカラムに
- カラムをNULL代入可にする
- デフォルト値を設定する
のどちらかを設定する必要があります。一番早いのはNull代入可にする方法なのですが、流石Slickさん、意外な障壁があります。普通ColumnOptionはTable#Oオブジェクトに定義されてると思うじゃないですか?違うんですよ。
以下がNullbaleを設定するコードになります。
import slick.driver.MySQLDriver.api._
import java.sql.Timestamp
import slick.profile.SqlProfile.ColumnOption // Table#OにNullableが無いので、これをimportしてくる
case class Hoge(
id : Long,
t1 : Timestamp,
t2 : Timestamp
)
class HogeTable(tag: Tag) extends Table[Hoge](tag, "Hoge"){
def id = column[Long]("id",O.PrimaryKey, O.AutoInc)
def t1 = column[Timestamp]("t1", ColumnOption.Nullable)
def t2 = column[Timestamp]("t2", ColumnOption.Nullable)
def * = (id, t1, t2) <> (Hoge.tupled, Hoge.unapply)
}
おまけ
ちなみに、
def t1 = column[Timestamp]("t1", O.Default(Timestamp(0)))
を設定するだけだと、NOT NULLのオプションが外れないので結局2つ以上Timestampは定義出来ません。
slickってこういう細かなところでハマりまくりますよね。。。