scala - How can I map a case class with non-default field types to a table in Slick? -
i can mapping case class slick database table:-
case class sometimestamp(id: option[long], timestamp: java.sql.timestamp ) class timestamptable(tag: tag) extends table[sometimestamp](tag, "tstamp_table") { def id = column[long]("id", o.autoinc, o.primarykey) def time = column[java.sql.timestamp]("time") def * = (id.?, time) <> (sometimestamp.tupled, sometimestamp.unapply) }
the case class has fields converted database types default slick, well.
but doesn't work, if field in case class not default database type. slick allows me provide implicit conversion , valid database type using mappedcolumntype, tried this, notice use java localdatetime thather sql timestamp.
case class somelocaldate(id: option[long], timestamp: java.time.localdatetime ) class localdatetable(tag: tag) extends table[somelocaldate](tag, "tldate_table") { import localdatetable._ def id = column[long]("id", o.autoinc, o.primarykey) def time = column[java.time.localdatetime]("time") def * = (id.?, time) <> (somelocaldate.tupled, somelocaldate.unapply) } object localdatetable { implicit val localdatetimetotimestamp = mappedcolumntype.base[localdatetime, timestamp]( { timestamp.valueof(_) } , { ts => ts.tolocaldatetime } ) }
i have added , implicit mapped column still compile error in projection , implicit resolution compile error is:-
[info] compiling 1 scala source ...target/scala-2.11/classes... [error] db/tables.scala:92: not find implicit value parameter tt: slick.ast.typedtype[java.time.localdatetime] [error] def time: rep[localdatetime] = column[java.time.localdatetime]("time")
if modify def time , add type ascription different error, see below.
case class somelocaldate(id: option[long], timestamp: java.time.localdatetime ) class localdatetable(tag: tag) extends table[somelocaldate](tag, "tldate_table") { import localdatetable._ def id = column[long]("id", o.autoinc, o.primarykey) def time: rep[localdatetime] = column[java.time.localdatetime]("time") def * = (id.?, time) <> (somelocaldate.tupled, somelocaldate.unapply) } object localdatetable { implicit val localdatetimetotimestamp = mappedcolumntype.base[localdatetime, timestamp]( { timestamp.valueof(_) } , { ts => ts.tolocaldatetime } ) }
gives error:-
[info] compiling 1 scala source ...target/scala-2.11/classes... [error] db/tables.scala:92: not find implicit value parameter tt: slick.ast.typedtype[java.time.localdatetime] [error] def time: rep[localdatetime] = column[java.time.localdatetime]("time") [error] ^ [error]db/tables.scala:94: no matching shape found. [error] slick not know how map given types. [error] possible causes: t in table[t] not match * projection. or use unsupported type in query (e.g. scala list). [error] required level: slick.lifted.flatshapelevel [error] source type: (slick.lifted.rep[option[long]], slick.lifted.rep[java.time.localdatetime]) [error] unpacked type: (option[long], java.time.localdatetime) [error] packed type: [error] def * = (id.?, time) <> (somelocaldate.tupled, somelocaldate.unapply) [error] ^ [error] 2 errors found
what have map case class table if case class not have default supported database types (eg localdatetime) ?
cheers
after days of struggling found answer :-/
the problem implicit mappedcolumntype declared after table class. reason upset implicit resolution though imported above table.
i found answer when removed case class , used tuples. when did following error presented
[info] compiling 1 scala source target/scala-2.11/classes... [error] /db/tables.scala:100: not find implicit value parameter tt: slick.ast.typedtype[java.time.localdatetime] [error] def time: rep[localdatetime] = column[java.time.localdatetime]("time") [error] ^ [error] /db/tables.scala:102: type mismatch; [error] found : (slick.lifted.rep[option[long]], slick.driver.h2driver.api.rep[java.time.localdatetime]) [error] (which expands to) (slick.lifted.rep[option[long]], slick.lifted.rep[java.time.localdatetime]) [error] required: slick.lifted.provenshape[(option[long], java.time.localdatetime)] [error] note: implicit value localdatetimetotimestamp not applicable here because comes after application point , lacks explicit result type [error] def * : provenshape[(option[long], localdatetime)] = (id.?, time) [error] ^
so clear solution put implicit conversion above table definition if in same file or put in file , import it, see working solution below. thanks.
case class somelocaldate(id: option[long], timestamp: java.time.localdatetime ) object localdatetableconversions { implicit val localdatetimetotimestamp = mappedcolumntype.base[localdatetime, timestamp]( { timestamp.valueof(_) } , { ts => ts.tolocaldatetime } ) } import localdatetableconversions._ class localdatetable(tag: tag) extends table[somelocaldate](tag, "tldate_table") { def id = column[long]("id", o.autoinc, o.primarykey) def time: rep[localdatetime] = column[java.time.localdatetime]("time") def * = (id.?, time) <> (somelocaldate.tupled, somelocaldate.unapply) }
Comments
Post a Comment