4

Whenever I get an update request for a given id , I am trying to update the masterId and the updatedDtTm columns in a DB table( I don't want to update my createdDtTm). The following is my code :

case class Master(id:Option[Long] = None,masterId:String,createdDtTm:Option[java.util.Date],
                      updatedDtTm:Option[java.util.Date])

/**
 * This is my Slick Mapping table
 * with the default projection
 */
`class MappingMaster(tag:Tag) extends
Table[Master](tag,"master") {

    implicit val DateTimeColumnType = MappedColumnType.base[java.util.Date, java.sql.Timestamp](
    {
      ud => new Timestamp(ud.getTime)
    }, {
      sd => new java.util.Date(sd.getTime)
    })
    def id = column[Long]("id",O.PrimaryKey,O.AutoInc)
    def masterId = column[String]("master_id")
    def createdDtTm = column[java.util.Date]("created_dttm")
    def updatedDtTm = column[java.util.Date]("updated_dttm")

    def * = (id.? , masterId , createdDtTm.? , updatedDtTm.?) <>
      ((Master.apply _).tupled , Master.unapply _) }

/**
 * Some where in the DAO update call
 */
db.run(masterRecords.filter(_.id === id).map(rw =>(rw.masterId,rw.updatedDtTm)).
update(("new_master_id",new Date()))

// I also tried the following
db.run(masterRecords.filter(_id === id).map(rw => (rw.masterId,rw.updatedDtTm).shaped[(String,java.util.Date)]).update(("new_master_id",new Date()))

The documentation of Slick states that inorder to update multiple columns one needs to use the map to get the corresponding columns and then update them.

The problem here is the following - the update method seems to be accepting a value of Nothing.

I also tried the following which was doing the same thing as above:

val t = for {
ms <- masterRecords if (ms.id === "1234")
} yield (ms.masterId , ms.updateDtTm)
db.run(t.update(("new_master_id",new Date())))

When I compile the code , it gives me the following Compilation Exception :

 Slick does not know how to map the given types.
[error] Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List).
[error]   Required level: slick.lifted.FlatShapeLevel
[error]      Source type: (slick.lifted.Rep[String], slick.lifted.Rep[java.util.Date])
[error]    Unpacked type: (String, java.util.Date)
[error]      Packed type: Any
[error]     db.run(masterRecords.filter(_id === id).map(rw => (rw.masterId,rw.updatedDtTm).shaped[(String,java.util.Date)]).update(("new_master_id",new Date()))

I am using Scala 2.11 with Slick 3.0.1 and IntelliJ as the IDE. Really appreciate if you can throw some light on this.

Cheers, Sathish

1 Answers1

5

(Replaces original answer) It seems the implicit has to be in scope for the queries, this compiles:

case class Master(id:Option[Long] = None,masterId:String,createdDtTm:Option[java.util.Date],
                    updatedDtTm:Option[java.util.Date])

implicit val DateTimeColumnType = MappedColumnType.base[java.util.Date, java.sql.Timestamp](
  {
    ud => new Timestamp(ud.getTime)
  }, {
    sd => new java.util.Date(sd.getTime)
  })

class MappingMaster(tag:Tag) extends Table[Master](tag,"master") {


    def id = column[Long]("id",O.PrimaryKey,O.AutoInc)  
    def masterId = column[String]("master_id")
    def createdDtTm = column[java.util.Date]("created_dttm")
    def updatedDtTm = column[java.util.Date]("updated_dttm")

    def * = (id.? , masterId , createdDtTm.? , updatedDtTm.?) <> ((Master.apply _).tupled , Master.unapply _)

}

private val masterRecords = TableQuery[MappingMaster]

val id: Long = 123

db.run(masterRecords.filter(_.id === id).map(rw =>(rw.masterId,rw.updatedDtTm)).update("new_master_id",new Date()))

val t = for {
  ms <- masterRecords if (ms.id === id)
} yield (ms.masterId , ms.updatedDtTm)
db.run(t.update(("new_master_id",new Date())))
User
  • 31,811
  • 40
  • 131
  • 232
  • Thank you for your answer , but this no different from what I tried earlier and this also yields a compilation issue. The following screen shot in IntelliJ indicates that query.update expects a value:Nothing and not a value:(String,java.util.Date). – Sathish Mandapaka Aug 11 '15 at 15:05
  • The update method is expecting a value of Nothing and hence if I use your code , IntelliJ Complains saying too many parameters to update method. Once again , I am using the latest Slick 3.0.1 , this seems to be working with slick 2.0 but my question is for Slick 3.0.1 – Sathish Mandapaka Aug 11 '15 at 15:11
  • Mhh I'm using Slick 3.0.0 – User Aug 11 '15 at 15:12
  • Update expecting a parameter of type Nothing doesn't make sense to me... how will it update then? Which driver are you using? I'm using MySQL, the update method is here (3.0.1 docs): `http://slick.typesafe.com/doc/3.0.1/api/index.html#slick.driver.JdbcActionComponent$UpdateActionExtensionMethodsImpl` – User Aug 11 '15 at 15:17
  • If I use the Tuple in the yield as you described - update expects Nothing [link]http://snag.gy/rZdVp.jpg . If I use only a single value which is a String in the yield - then the update method expects a String value [link] http://snag.gy/QpWV7.jpg – Sathish Mandapaka Aug 11 '15 at 15:17
  • The code looks ok to me... my IDE doesn't even autocomplete update, but it compiles... did you try passing the values (*not* as tuples) as I posted, and compile? – User Aug 11 '15 at 15:23
  • Actually, the brackets doesn't seem to be the issue, I can use with or without brackets in 3.0.0, both compile... – User Aug 11 '15 at 15:26
  • Wait a sec, you have a problem with the datatypes - in the first code id is a `Long` and you compare with `Option[Long]`. In the second you are comparing it to a `String`. You have to use a `Long`. – User Aug 11 '15 at 15:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/86713/discussion-between-sathish-mandapaka-and-ixx). – Sathish Mandapaka Aug 11 '15 at 15:32