Search code examples
scalaplayframeworkslickslick-2.0

Returning the auto incrementing value after an insert using slick


I am using slick 2.0.1 (and can upgrade if required) and I want to retrieve the auto incrementing value from the database (postgresql).

I have seen a few questions on SO on this already, but they are fairly old and I was hoping there was a better way than to do what this answer suggests: Scala & Play! & Slick & PostgreSQL auto increment

def autoInc = name ~ price ~ description returning id

def add(product: Product)(implicit s:Session): Long = {
    Products.autoInc.insert(p.name, p.price, p.description)
}

You have to re-enter the model's fields in the autoInc method, which is duplicating things which I am hoping to avoid.

Is there a better way or I should just do it like this?

The way I have chosen is to have my models poso (plain old scala objects like):

case class Product(.....)

And then my dao class looks like:

class ProductDao extends ProductDao {
  class Products(tag: Tag) extends Table[Product](tag, "products") {

     def id = ...
     def name = ..

     def * = (id, name) <> (Product.tupled, Product.unapply)

  }

  val products = TableQuery()
}

Also as a side note, for the * method do I have to enter all the properties like that or is there a better way for that also?


Solution

  • The autoInc or forInsert projection pattern you have seen applies to Slick 1 but not Slick 2, where auto incremented values are automatically ignored in inserts. See http://slick.typesafe.com/doc/2.0.2/migration.html#inserting

    Can you better than repeating your column names? Or multiple manifestations of artifacts of your data model for that matter? Code generation is one way to do it: http://slick.typesafe.com/doc/2.0.2/code-generation.html I will be speaking about this at Scala days.

    For returning the id use returning just like in Slick 1. http://slick.typesafe.com/doc/2.0.2/queries.html#inserting