PSQLException: ERROR: null value in column "id" violates not-null constraint

12,377 views
Skip to first unread message

Michael Slinn

unread,
Mar 17, 2013, 8:56:11 PM3/17/13
to scala...@googlegroups.com
I just converted a Play 2.1 app that used Slick and MySQL to Postgres. The program worked fine under MySQL. I am left with one problem after the conversion:

PSQLException: ERROR: null value in column "id" violates not-null constraint

The DDL is:

CREATE TABLE "role" (
  "userId" character varying(254) NOT NULL,
  "name" character varying(254) NOT NULL,
  "refName" character varying(254),
  "id" BIGSERIAL PRIMARY KEY
)
WITHOUT OIDS;



Scala:

import play.api.Play.current
import play.api.db.DB
import slick.session.{Session, Database}
import slick.driver.PostgresDriver.simple._

object Roles extends Table[Role]("role")  {
  lazy val database = Database.forDataSource(DB.getDataSource())

  def userId  = column[String]("userId", O.NotNull)
  def name    = column[String]("name", O.NotNull)
  def refName = column[Option[String]]("refName")
  def id      = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)

  def *       = userId ~ name ~ refName ~ id <> (Role, Role unapply _)

  def autoInc = * returning id

  def add(role: Role) = database.withSession { implicit session: Session =>
    Roles.autoInc.insert(role)
  }

  def apply(userId: String, name: String, refName: Option[String]=None, id: Option[Long]=None) =
    Role(userId, name, refName, id)

  def save(role: Role): Option[Long] = database.withSession { implicit session: Session =>
    autoInc.insert(role)    //==== blows up here ====
  }
}

case class Role(userId: String,  name: String, refName: Option[String] = None, id: Option[Long] = None)


Suggestions?

Mike

Jason Giedymin

unread,
Mar 18, 2013, 12:24:47 AM3/18/13
to scala...@googlegroups.com
Try removing the not null attr from id. 

-Jason
--
 
---
You received this message because you are subscribed to the Google Groups "Slick / ScalaQuery" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scalaquery+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Mike Slinn

unread,
Mar 18, 2013, 12:34:27 AM3/18/13
to scala...@googlegroups.com, Jason Giedymin
Jason,

I did not explicitly specify NOT NULL, as you can see. However, SERIAL
and BIGSERIAL are essentially macros that generate NOT NULL. Postgres
docs say to use SERIAL and BIGSERIAL for cases where you would use
AUTOINC for MySQL, however there are differences between how Postgres
and MySQL work in this and other regards.

Are you using Postgres with Slick, and if so are you using SERIAL or
BIGSERIAL? It would be great if you would show some working code to
compare with what I've shown.

Thanks,

Mike

Jason

unread,
Mar 18, 2013, 12:57:13 AM3/18/13
to Mike Slinn, scala...@googlegroups.com
Hm...

I am on a netbook atm so not sure if this works but I saw that your ID is set as Option and the projection has no option fill (It's late, maybe I'm reading wrong!):

def * = userId ~ name ~ refName.? ~ id.? <> (Role, Role unapply _)
def autoInc = * ~ id.? <> (Role, Role unapply _) returning id


Christopher Vogt

unread,
Mar 18, 2013, 10:30:57 AM3/18/13
to scala...@googlegroups.com, Jason Giedymin
Why is id a PrimaryKey / AutoInc but at the same time an Option?

Mike Slinn

unread,
Mar 18, 2013, 10:55:06 AM3/18/13
to scala...@googlegroups.com, Christopher Vogt, Jason Giedymin
What is the recommended incantation?

Thank you,

Mike

Jason Giedymin

unread,
Mar 18, 2013, 11:14:15 AM3/18/13
to Mike Slinn, scala...@googlegroups.com, Christopher Vogt
In role case make it option,

But where you define id with column[ ] it can be without,

See my snippet I sent earlier

-Jason

Mike Slinn

unread,
Mar 18, 2013, 11:44:03 AM3/18/13
to Jason Giedymin, scala...@googlegroups.com, Christopher Vogt, stefan...@typesafe.com
This issue is holding up our beta release.

I tried changing these lines:

def id      = column[Long]("id", O.PrimaryKey, O.AutoInc)
def *       = userId ~ name ~ refName ~ id.? <> (Role, Role unapply _)


  def save(role: Role): Option[Long] = database.withSession { implicit session: Session =>
    Some(autoInc.insert(role))
  }

However the results were exactly the same. Has autoinc been tested with Postgres, using a primary key defined with SERIAL or BIGSERIAL?

Thank you,

Mike

Jason Giedymin

unread,
Mar 18, 2013, 1:24:11 PM3/18/13
to scala...@googlegroups.com

And case class Role continues to use id:Option[ ] right?

If you want you could try using explicit this reference for Role

Roles.autoInc.insert...

Probably a good time to create a gist as well, tonight ill try to duplicate this issue.

-Jason
--

Mike Slinn

unread,
Mar 18, 2013, 2:38:30 PM3/18/13
to scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt, stefan...@typesafe.com
This is definitely a Slick bug that shows up with Postgres but not
MySql. I did not see any Slick unit tests that covered using autoInc
with the * projection. The workaround is to modify the definition of
autoInc so that it does not reference the * projection, like this:

object Roles extends Table[Role]("role") {
lazy val database = Database.forDataSource(DB.getDataSource())

def userId = column[String]("userId", O.NotNull)
def name = column[String]("name", O.NotNull)
def refName = column[Option[String]]("refName")
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)

def * = userId ~ name ~ refName ~ id.? <> (Role, Role unapply _)

def autoInc = userId ~ name ~ refName returning id

def add(role: Role) = database.withSession { implicit session: Session =>
autoInc.insert(role.userId, role.name, role.refName)
}
}

This workaround results in more verbose and error-prone code, but it
lets us move forward with launching.

Mike

Jason Giedymin

unread,
Mar 18, 2013, 3:00:56 PM3/18/13
to scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt, stefan...@typesafe.com
That was going to be my last suggestion. :-p

Julien L.

unread,
Mar 22, 2013, 11:11:03 AM3/22/13
to scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt, stefan...@typesafe.com
+1, I've the same problem (Autoincrement with PosgresSQl).

This workaround works fine, but it's extremly verbose and error prone (especially if you've a 15 fields in your table...)

Christopher Vogt

unread,
Mar 22, 2013, 12:08:47 PM3/22/13
to scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt, stefan...@typesafe.com
we'll look into it

Mike Slinn

unread,
Mar 22, 2013, 12:42:17 PM3/22/13
to scala...@googlegroups.com, Julien L., Jason Giedymin, Jan Christopher Vogt, stefan...@typesafe.com
I agree, the requirement for this workaround means that I would not
recommend Slick to Postgres users.

Mike

Stefan Zeiger

unread,
Apr 12, 2013, 10:21:25 AM4/12/13
to Mike Slinn, scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt
On 2013-03-18 19:38, Mike Slinn wrote:
This is definitely a Slick bug that shows up with Postgres but not MySql. I did not see any Slick unit tests that covered using autoInc with the * projection. The workaround is to modify the definition of autoInc so that it does not reference the * projection, like this:

Using a separate projection is the correct solution. This is not a bug in Slick but a missing feature (which would have been difficult to implement in the old codebase but should be doable with the new type encoding that is coming in Slick 2.0): https://github.com/slick/slick/issues/27

--
Stefan Zeiger
Typesafe - The software stack for applications that scale
Twitter: @StefanZeiger

See you at Scala Days 2013 in NYC!
June 10th - June 12th
www.scaladays.org

Mike Slinn

unread,
Apr 12, 2013, 10:46:38 AM4/12/13
to Stefan Zeiger, scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt
Stefan,

Code that runs on Slick + MySQL does not compile against Slick +
Postgres. I would call that a bug.

There should be a comprehensive suite of tests against all supported
databases, not just an in-memory database. This would ensure that Slick
behaves consistently regardless of the database that it is connected to.
If this was done, the bug would have been caught.

Thank you,

Mike

Stefan Zeiger

unread,
Apr 12, 2013, 12:24:25 PM4/12/13
to Mike Slinn, scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt
On 2013-04-12 16:46, Mike Slinn wrote:
Stefan,

Code that runs on Slick + MySQL does not compile against Slick + Postgres. I would call that a bug.

I would call it reality. It's unavoidable unless we want to lock everything down to the smallest subset supported by all database systems. It's also unavoidable that some errors will only be detected at runtime.


There should be a comprehensive suite of tests against all supported databases, not just an in-memory database. This would ensure that Slick behaves consistently regardless of the database that it is connected to. If this was done, the bug would have been caught.

We do run all tests against all supported databases. This has not been caught because it is not a bug. It is expected to fail (and required by the SQL standard) but some database systems allow it nevertheless. Our policy in general is not to disable database features on purpose but to add capability flags instead. Inserting values into AutoInc columns has always been discouraged so there is no flag to check for that. Just don't do it.

Mike Slinn

unread,
Apr 12, 2013, 12:54:32 PM4/12/13
to Stefan Zeiger, scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt
Stefan,

1) "Discouraged"? No warnings are mentioned in the documentation.
2) I did not show any code that inserted into an autoinc column.
3) No other persistence mechanism that I am aware of restricts a value from being supplied for autoinc. Why should Slick be different?
4) I do not see tests for MySQL, Postgres or other supported databases in the Slick project. Where are these tests that you refer to?
5) Your responses have wandered from the original topic I posted. If you refer back to my original posting, I reported a compilation error on valid Slick code that worked for MySQL and not for Postres. If Slick is not expected to behave consistently for all databases, then the documentation needs to say this in big red bold type, and there would be little interest in using it. Corner cases are understandable, but the issue I reported is a mainstream, in-your-face problem. The workaround is to replicate long strings of fragile code, violating DRY. My situation is that 22 fields (the maximum supported) must be recited in 6 places in the persistence code for one of the domain objects. This leads to fragile code, and bugs have been found in our code that result from some fields being out of order after the schema is modified. Each time a change is made, all six incantations must be modified. Other domain objects have similar redundant incantations. If this bug was fixed, then the number of recitations would be reduced by one. If there was proper documentation for Slick, it may well turn out that additional recitations could be removed.

Currently some of our domain objects are persisted using other means, due to Slick limitations. We want to consolidate to using only one persistence mechanism. Once we catch our breath, we'll revisit the continued suitability of Slick for our project.

Thank you,

Mike

Stefan Zeiger

unread,
Apr 12, 2013, 1:20:36 PM4/12/13
to Mike Slinn, scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt
On 2013-04-12 18:54, Mike Slinn wrote:
Stefan,

1) "Discouraged"? No warnings are mentioned in the documentation.

http://slick.typesafe.com/doc/1.0.0/lifted-embedding.html#inserting

" While some database systems allow inserting proper values into AutoInc columns or inserting None to get a created value, most databases forbid this behaviour, so you have to make sure to omit these columns. Slick does not yet have a feature to do this automatically but it is planned for a future release. For now, you have to use a projection which does not include the AutoInc column, like forInsert in the following example"


2) I did not show any code that inserted into an autoinc column.

Yes, you did:

object Roles extends Table[Role]("role")  {
  lazy val database = Database.forDataSource(DB.getDataSource())

  def userId  = column[String]("userId", O.NotNull)
  def name    = column[String]("name", O.NotNull)
  def refName = column[Option[String]]("refName")
  def id      = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)

  def *       = userId ~ name ~ refName ~ id <> (Role, Role unapply _)

  def autoInc = * returning id


  def add(role: Role) = database.withSession { implicit session: Session =>
    Roles.autoInc.insert(role)
  }

  def apply(userId: String, name: String, refName: Option[String]=None, id: Option[Long]=None) =
    Role(userId, name, refName, id)

  def save(role: Role): Option[Long] = database.withSession { implicit session: Session =>
    autoInc.insert(role)    //==== blows up here ====
  }
}

3) No other persistence mechanism that I am aware of restricts a value from being supplied for autoinc. Why should Slick be different?

Inserting into an AutoInc column has no defined meaning. The only reason to allow it is for convenience. And if I spent less time reiterating my points here I would have more time to implement these conveniences (which are apparently not inconvenient enough for anyone else to step up and do so).


4) I do not see tests for MySQL, Postgres or other supported databases in the Slick project. Where are these tests that you refer to?

TestKit is run against all configured databases. See https://github.com/slick/slick/blob/master/test-dbs/databases.properties.example for instructions on how to set this up.


5) Your responses have wandered from the original topic I posted. If you refer back to my original posting, I reported a compilation error on valid Slick code that worked for MySQL and not for Postres.

I don't see any compilation error there, only a runtime error.


If Slick is not expected to behave consistently for all databases, then the documentation needs to say this in big red bold type, and there would be

I'm sorry, I don't think we have big red bold type in our style sheet. Why don't you submit a pull request?

Christopher Vogt

unread,
Apr 12, 2013, 6:28:12 PM4/12/13
to scala...@googlegroups.com, Mike Slinn, Jason Giedymin, Jan Christopher Vogt

If Slick is not expected to behave consistently for all databases, then the documentation needs to say this in big red bold type
Mike, we do support features in Slick which are not supported by all of the database backends. It would not be practical to limit Slick to the common subset of features of all backends. The features are for example reflected in the capabilities the drivers declare (see https://github.com/slick/slick/blob/master/src/main/scala/scala/slick/driver/AccessDriver.scala) and which you can check for at runtime (see https://github.com/slick/slick/blob/master/slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/DataTypeTest.scala). Your particular case is not reflected in a capability, but documented as Stefan mentioned. Maybe it could be made more obvious as you suggested or made a capability. The profile architecture of the drivers (see for example https://github.com/slick/slick/blob/master/src/main/scala/scala/slick/profile/SqlProfile.scala) also relates to this. You can generalize your app to use SqlProfile instead of particular driver.

Since not all features are portable to all backends, predictability of portability is important. Capabilities and profiles can help here. Just to be sure, I will bring the topic up in the next Slick team meeting, so we can review the current status and see if we need to improve here.

Mike Slinn

unread,
Apr 13, 2013, 3:16:06 AM4/13/13
to Christopher Vogt, scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt
Chris,

I'll take a moment to describe what I expect from a persistence mechanism. The 'whole product' is much more than just the code.
  1. Abstraction of common functionality. This implies behavioral consistency.
    1. Common operations such as querying, updating and inserting, as well as views should be database independent. Comprehensive unit tests should be run against every supported database.
    2. If a database is so different (for example, a non-relational database) that SQL concepts do not apply, then we are talking about an entirely separate category of persistence. Within a category, for example database that have drivers that support core JDBC 4 features, common concepts should work consistently between databases.
    3. Common tasks should be simple to express, and unique tasks should be possible.
    4. If I understand this thread correctly, functional abstraction has not been a goal for Slick. I pray that this is a misunderstanding.
  2. DRY. The fewer times something needs to be expressed, the more reliable a program is.  The current implementation of Slick does not support DRY user programs effectively.
  3. Integration with supported language versions and other products. For Slick, this means integration with Scala and Play. Integration means that use cases are supported for the facilities exposed by supported products. Slick seems to have been developed in isolation, and Play integration in particular is weak.
    1. Detailed documentation exploring the boundary between Scala collections and the Slick DSL would be helpful. 
    2. Another example: pagination is required for most web applications, but not much mention is made in the documentation. If a result set was cached, would connections be used up as concurrent user queries grew, or should temporary tables be used - what are best practices?
  4. Extensibility. An API for additional drivers, a facility for modifying and extending generated SQL, and implementing additional functionality such as full text search, etc. This is a secondary consideration.
  5. User documentation - the most pressing issue at this time.
    1. Concepts should be expressed from a user perspective, including a detailed commentary for each and every class, operator and method, and how they interact. For example, the Lifted Embedding documentation explains several concepts in terms of a Rep, but there is no definition of that class's purpose. Users should not have to read source code in order to understand fundamental concepts.
    2. Terms should be defined; for example, the term 'projection' is not defined. Another example is "Query" and "Queryable", which are not properly described; both of these are casually mentioned without introduction in a few places in the documentation, but the reader is left wondering what they are, when and how they should be used. A glossary might be helpful.
    3. There should be complete working examples for common use cases, and a summary of best practices and optimization techniques. The coffee examples are overly simplistic. For example, detailed discussions of working code examples showing indices, foreign keys and every type of supported join would be helpful. Autoincrement fields are very common, yet the coffee example, used throughout the documentation, does not feature any table with an autoincrement field, nor is there any code example or description of how to work with autoincrement.
    4. If there are implementation deficiencies, those should be noted. For example, the 22 field limit for lifted embedding, and complete code examples of how to work around the limitation. A search of the current documentation shows no mention of 22, yet this is an important limitation. It is not helpful to say that a future version will solve any given problem, instead a serious attempt should be made to show workarounds for the current implementation and the tradeoffs for each workaround.
    5. A comparison of various ways of expressing similar concepts, and a discussion perhaps even including benchmarks to illustrate performance differences between approaches. 
    6. Prior to the 1.0 milestone, it was stated that better documentation would follow shortly after the 1.0 release. I have not yet noticed a significant change in the quantity or quality of the Slick documentation.
      1. For example, it would be helpful to have additional documentation on type mappers.
      2. Most operators have no documentation at all.
      3. Many topics discussed in the ML are not mentioned in the documentation, and the information mentioned on the ML  has not been worked back into the documentation, nor has it been expressed in its entirety. The result is fragmented folk lore.
  6. Road map. A detailed road map describing future milestones with timeframes should be publicly maintained.
Resources for every project are always finite. I suggest that focus be put on the documentation for the current implementation. Better documentation would help adoption, and would provide common ground for discussions of future direction.

Thank you,

Mike

Christopher Vogt

unread,
Apr 19, 2013, 12:12:09 PM4/19/13
to scala...@googlegroups.com, Christopher Vogt, Jason Giedymin, Jan Christopher Vogt
Hi Mike,


> Abstraction of common functionality. This implies behavioral
> consistency.

Slick's power are very expressive, composable and language integrated
queries in Scala. We provide behavioral abstraction where we can and
where we see demand (meaning missing abstraction is a feature request,
not a bug). We doubt that complete abstraction can be realistically
achieved for a library with powerful queries like Slick and would
certainly consume significant human resources which we do not have. The
same features sometimes have subtle differences in their behavior in
different databases and often accordingly in our backends. The details
of these differences partly depend on the configuration of the database
server, which Slick doesn't know about. ORM frameworks usually opt for
less powerful queries, which can be made 100% consistent easily. We do
not want to restrict Slick's power. Instead we provide slick-testkit, a
framework, with which you can run tests against multiple backends to
assure portability.

You can improve portability of your queries by parameterizing it with
one of the superclasses of the drivers (BasicProfile/SqlProfile). Also
note that some of the limitations of certain backends are documented as
capabilities in the driver code and api docs. The general documentation
also contains hints regarding portability of particular features as
Stefan pointed out.


> DRY. The fewer times something needs to be expressed, the more
> reliable a program is. The current implementation of Slick does not
> support DRY user programs effectively.

DRY is good. Which cases are you thinking about exactly? There are a
small number cases where Slick forces user programs to break dry. They
are a artifacts of Slick's type-safe query feature and can only be
solved by code-generation, which we release as type providers. Amir is
heavily working on them
(https://github.com/slick/slick/commits/topic/type-providers) and is
making good progress.


> Integration with supported language versions and other products. For
> Slick, this means integration with Scala and Play.

What do you mean by integration with Scala versions? I can't say
anything about Slick Play integration myself, but I am sure the guys at
Typesafe working on it have open ears for your suggestions. Maybe create
another thread for that and mention your particular problems or suggestions.


> Detailed documentation exploring the boundary between Scala
> collections and the Slick DSL would be helpful.

What do you mean by boundaries?


> Another example: pagination is required for most web applications, but
> not much mention is made in the documentation. If a result set was
> cached, would connections be used up as concurrent user queries grew,
> or should temporary tables be used - what are best practices?

I agree, the documentation needs work. Trying to use Slick like Scala
collections works in many cases. For pagination you can use drop and
take documented here:
http://slick.typesafe.com/doc/1.0.0/api/#scala.slick.lifted.Query
(I am wondering why it is not showing up in the Scaladoc alphabetic
index. Anybody an idea?)
Be aware that there is a pagingDrop capability, which the AccessDriver
does not support for example.


> Extensibility. An API for additional drivers, a facility for modifying
> and extending generated SQL, and implementing additional functionality
> such as full text search, etc. This is a secondary consideration.

Custom drivers are an advanced feature, which are very well supported by
Slick.


> User documentation - the most pressing issue at this time.

Documentation has improved. The latest documentation is only in the
repository. We are working on publishing nightly builds (expect them in
a few weeks), which will also publish the latest documentation versions.
But certainly the documentation needs further improvements. It is also
important to note that we need most of our resources to satisfy agreed
upon milestones for Typesafe's customers. We welcome contributions to
outstanding issues like documentation.

Chris

Mike Slinn

unread,
Apr 19, 2013, 12:41:44 PM4/19/13
to scala...@googlegroups.com, Christopher Vogt, Jason Giedymin, Jan Christopher Vogt
Chris,

I disagree with the premise that power of expression is more important
than consistency. Without consistency, expressiveness is not portable
and hence looses value for most users.

The ML has lots of discussion about issues with DRY, and Stefan has
participated in them.

If your group is not working with the Play group, that would explain the
lack of integration. "The guys at Typesafe" also suggests that the
partnership with EFPL is not an effective working relationship for
product development. Slick is promoted as a Typesafe product, but the
two full-time team members are employed by EPFL, in a university
research setting, and there are no Typesafe employees dedicated to
driving commercial interests for Slick forward. This explains the
failure to engage with the Play team.

The difference between a research project and a commercial project is
immense. Clearly the business arrangement between EPFL and Typesafe
needs to be addressed before technical issues can be worked out, or
perhaps the team should transition to becoming Typesafe employees.

Thank you,

Mike

virtualeyes

unread,
Apr 20, 2013, 6:33:19 AM4/20/13
to scala...@googlegroups.com, Christopher Vogt, Jason Giedymin, Jan Christopher Vogt
Well, that's quite a laundry list.

You have some valid points, but keep in mind, TypeSafe is not M$; i.e. don't expect sudden miracles on your "what I expect from a persistence mechanism" list, chef ;-)

As you likely know Slick derives from ScalaQuery, a project Stefan created on his own without financial backing of any kind (HUGE thanks to Stafen!); TypeSafe took notice (of the high level work) and hired him to lead further develop of the project (along with Chris).

Documentation has always been a weak point. Stefan is the wrong person for this task, clearly, he's too involved in genius developer mode to deal with the drudgery of proper documentation. If you use an IDE, use it. I learned more about the Scala language through ScalaQuery source code than I did in any other library (although Play source has been pretty revealing as well).

At this point you have to roll up your sleeves and dig around, get your feet wet, and have at it. Check out GitHub project Fink for an alternative to cake pattern approach; that should help with Play integration. I created a DAO repository inspired by Fink, pretty indispensable, just supply to Play controller package objects and repo.user.get(11), repo.orders.findByDate(someJodaDate), and so on.

Tuple 22 is a language limitation, one that I hit in my first Play project. I managed a decent workaround with nested forms and breaking up affected DB tables (I know, not an option for some). Can try to create views or other DB-centric approach until Scala itself provides Tuple 200 support (that may be a long wait based on ML threads, perhaps of the hell freezing over variety)

Bottomline is you have to get creative: Scala ecosystem is young and a fast moving stream at that -- adapt and thrive should be the TypeSafe slogan ;-)

Hopefully within the year we'll see Type Providers and other boilerplate reducing fun coming our way, but for now, just deal with the BP, it's all compiler checked.

I bet if you look at your existing code base, focusing on the positive elements, you'll probably say, wow, this incredible stuff -- sure there are some warts, but overall I am loving this compared to X other language/stack.

That's how it is for me at any rate...

Mike Slinn

unread,
Apr 20, 2013, 7:04:42 AM4/20/13
to scala...@googlegroups.com, virtualeyes, Christopher Vogt, Jason Giedymin, Jan Christopher Vogt
Noah,

You essentially describe the mindset of an early adopter. However, the cost of reverse engineering a product in order to understand well enough to use it is very high, and will prevent Scala from cross the chasm into mainstream usage by 'pragmatists', à la Geoffrey Moore. I believe that persistence support is currently Scala's biggest weakness. While I hope that the Scala toolchain will be in a position to support mainstream usage by the end of 2013, there is still have a long way to go.

Best,

Mike

virtualeyes

unread,
Apr 20, 2013, 7:43:00 AM4/20/13
to scala...@googlegroups.com, virtualeyes, Christopher Vogt, Jason Giedymin, Jan Christopher Vogt
It's true there's a cost involved in learning ScalaQuery/Slick, but then again, 2 years ago I was just starting out in Scala itself, so diving into Stefan's code was immensely helpful on all fronts.

I'd actually argue that persistence support is a Scala strength -- currently there's Slick, Queryl, and Sqltyped on offer, along with Lift Mapper/Record, Rogue, and others. Pretty impressive lineup, IMO.

Nothing is perfect in Scala, but most of it is very good, and getting better.

I think Scala 2.11 is going to be the breakthrough time -- we'll have (if the promise is met) faster build times, macros evolved, and the latest & greatest of TypeSafe stack.

My biggest gripe in TypeSafe land is with Play and (very) long build times. I have yet to refactor into new multi-project support (talk about light documentation ;-)), and assets generation is a real PITA, dog slow -- ideally one could hack out the great features of Play (form generation/validation, controllers/action composition) and combine with Scalatra, Spray, or other micro framework.

For now full stack Play seems to be the best option out there, so staying put....

Mike Slinn

unread,
Apr 20, 2013, 8:10:16 AM4/20/13
to scala...@googlegroups.com, virtualeyes, Christopher Vogt, Jason Giedymin, Jan Christopher Vogt
I am also facing really long builds on the Play project I am working on,
and the build time seems to grow exponentially with the number of source
files. Play modules do not seem well supported, but I have been
successful factoring out controller logic into libraries. It is true
that Play docs leave much to be desired, even the Play books.

The Akka project shows what is possible in terms of putting together a
commercial product offering, and sets a high standard. I hope that the
same leadership style, processes and culture that evolved for that
project is infused into the Slick and Play projects. I believe we have
seen some of this happen with the Scala compiler project already.

Mike

Christopher Vogt

unread,
Apr 21, 2013, 5:57:05 AM4/21/13
to scala...@googlegroups.com, Christopher Vogt, Jason Giedymin, Jan Christopher Vogt
Yes, we couldn't avoid the DRY issues so far without code-generation. We are addressing them with type-providers.

There are statements about our project structure in your post, many of which are false. Maybe a little less speculation from your side :)? Here is some insight: I am the only EPFL employee on the Slick project, the rest is all Typesafe, which is located next door from our offices at EPFL. I am employed as an engineer to work on Slick, not as a researcher. Slick is a commercial product developed by Typesafe. Yes, documentation could be better and we are working on it, but this situation is not unheard of in world of commercial Scala software. There are indeed role models like Akka. Regarding Play, please ask in a separate thread if you have particular issues. Slick core development and Slick-Play interop are done in separate projects the latter of which is lead by Frederik.

In some cases Slick may have a different philosophy than you expect. This can be related to the fact that Slick is not an object-relational mapper (which many people are familiar with), but a functional-relational mapper (avoiding the object-relational impedance mismatch). We will give a talk about the differences and Slick's benefits at Scala Days in NYC in June, which will hopefully clear up some of the confusion.

Daghan Altas

unread,
Apr 12, 2014, 10:37:38 AM4/12/14
to scala...@googlegroups.com, Jason Giedymin, Jan Christopher Vogt, stefan...@typesafe.com
Mike,

I am also stuck on this but with Slick 2.0.1.
I am a newbie to Slick / Scala and unfortunately I can't use your workaround since their default projection syntax has changed:
From:
def *       = userId ~ name ~ refName ~ id.? <> (Role, Role unapply _) 
To: 

def * = (userId, name, refName, id.?) <> (Role, Role.unapply)  // I think

So the "autoinc" workaround doesn't seem to work.
Do you have any suggestions?

Thanks.


Christopher Vogt

unread,
Apr 12, 2014, 2:05:08 PM4/12/14
to scala...@googlegroups.com
Hi Daghan,

autoInc columns are automatically ignored for inserts in Slick 2, which
probably solves your problem.

Besides, you can import TupleMethods._ to get the old syntax back.

Chris

On 12.04.14 16:37, Daghan Altas wrote:
> Mike,
>
> I am also stuck on this but with Slick 2.0.1.
> I am a newbie to Slick / Scala and unfortunately I can't use your
> workaround since their default projection syntax has changed:
> From:
> def * = userId ~ name ~ refName ~ id.? <> (Role, Role unapply _)
> To:
>
> def * = (userId, name, refName, id.?) <> (Role, Role.unapply) // /I think/
>
> So the "autoinc" workaround doesn't seem to work.
> Do you have any suggestions?
>
> Thanks.
>
> /
> /
>
>
> On Monday, March 18, 2013 11:38:30 AM UTC-7, Michael Slinn wrote:
>
> This is definitely a Slick bug that shows up with Postgres but not
> MySql. I did not see any Slick unit tests that covered using autoInc
> with the * projection. The workaround is to modify the definition of
> autoInc so that it does not reference the * projection, like this:
>
> object Roles extends Table[Role]("role") {
> lazy val database = Database.forDataSource(DB.getDataSource())
>
> def userId = column[String]("userId", O.NotNull)
> def name = column[String]("name", O.NotNull)
> def refName = column[Option[String]]("refName")
> def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
>
> def * = userId ~ name ~ refName ~ id.? <> (Role, Role
> unapply _)
>
> def autoInc = userId ~ name ~ refName returning id
>
> def add(role: Role) = database.withSession { implicit session:
> Session =>
> autoInc.insert(role.userId, role.name <http://role.name>,
> role.refName)
> }
> }
>
> This workaround results in more verbose and error-prone code, but it
> lets us move forward with launching.
>
> Mike
>
> --
>
> ---
> You received this message because you are subscribed to the Google
> Groups "Slick / ScalaQuery" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to scalaquery+...@googlegroups.com
> <mailto:scalaquery+...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/scalaquery/3740b7a7-dd01-43df-a5bd-dcc6482514e0%40googlegroups.com
> <https://groups.google.com/d/msgid/scalaquery/3740b7a7-dd01-43df-a5bd-dcc6482514e0%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

--
Jan Christopher Vogt
Slick/Scala Team
Switzerland

Daghan Altas

unread,
Apr 13, 2014, 8:27:34 PM4/13/14
to scala...@googlegroups.com
Hi Chris,

Thank you very much for the answer (and let me take the opportunity to thank also for SLICK. I love it)
I will try to import TupleMethods._ to get the old syntax back.

As for the original question, I see that Slick ignores autoInc columns.
But that column is the primary key for the table:

    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)

Postgres automatically makes my column non-null:

Column  |              Type              | Modifiers 

---------+--------------------------------+-----------

 id      | integer                        | not null

And when I try to insert a new column via Slick,
I get this following error:org.postgresql.util.PSQLException: ERROR: null value in column "id" violates not-null constraint.

All this is perhaps because I don't fully understand and therefore fix the default projection in my table definition, not sure...

I'd greatly appreciate if you have any further insight.

Daghan Altas

unread,
Apr 13, 2014, 11:58:01 PM4/13/14
to scala...@googlegroups.com
Hi Chris,

I fixed my problem. It had nothing to do with SLICK. 
I just didn't know enough Postgres.

Changing the id column (primary key) type from integer to serial did the trick. Everything works now. 

Here is what the type change did:

Before:

Column  |              Type              | Modifiers
---------+--------------------------------+-----------
 id      | integer                        | not null

After:
Column |         Type          |                     Modifiers                      
--------+-----------------------+----------------------------------------------------
 id     | integer               | not null default nextval('tests_id_seq'::regclass)


Rene Bolecek

unread,
Sep 27, 2015, 12:39:22 AM9/27/15
to Slick / ScalaQuery
Thanks Daghan Altas, makes me have the first woking sample (https://github.com/renexdev/play-slick-computer-database-mod) with  play 2.4, play-slick 1.0.0. Cheers
Rene 
Reply all
Reply to author
Forward
0 new messages