In my Play + Slick 3.2.1 (using PlaySlick 3.0.0) project, I'm trying to have a nullable column password_id
on a table user
:
case class User(id: Long, name: String, passwordId: Option[Long]) extends Identity
class UserTable(tag: Tag) extends Table[User](tag, "user") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name", O.Unique)
def passwordId = column[Option[Long]]("password_id", O.Unique)
def password = foreignKey("password", passwordId, Passwords.passwords)(_.id)
override def * = (id, name, passwordId) <> (User.tupled, User.unapply)
}
Table creation in evolutions script:
create table user (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR NOT NULL UNIQUE,
password_id BIGINT UNIQUE,
FOREIGN KEY(password_id) REFERENCES password(id)
);
Now, when I'm trying to insert a new user into that table as follows
def dbConfig = DatabaseConfigProvider.get[JdbcProfile](Play.current)
dbConfig.db.run(users += User(0, "test", None))
I run into an exception:
slick.SlickException: Read NULL value (null) for ResultSet column <computed>
at slick.jdbc.SpecializedJdbcResultConverter$$anon$1.read(SpecializedJdbcResultConverters.scala:27)
at slick.jdbc.SpecializedJdbcResultConverter$$anon$1.read(SpecializedJdbcResultConverters.scala:24)
at slick.relational.ProductResultConverter.read(ResultConverter.scala:56)
at slick.relational.ProductResultConverter.read(ResultConverter.scala:46)
at slick.relational.TypeMappingResultConverter.read(ResultConverter.scala:136)
at slick.jdbc.JdbcInvokerComponent$QueryInvokerImpl.extractValue(JdbcInvokerComponent.scala:36)
at slick.jdbc.StatementInvoker$$anon$1.extractValue(StatementInvoker.scala:67)
at slick.jdbc.PositionedResultIterator.fetchNext(PositionedResult.scala:176)
at slick.util.ReadAheadIterator.update(ReadAheadIterator.scala:28)
at slick.util.ReadAheadIterator.hasNext(ReadAheadIterator.scala:34)
...
To me, this indicates that Slick still interprets password_id
as non-nullable.
Am I missing something in my config, or might this be a bug?
(For what it's worth, I couldn't find any example/seed project for Slick 3.x using nullable columns at all.)
Update: Mystery solved
After further investigation it turns out I've been looking in the wrong place.
There was a different table with a property not declared as nullable (i.e. Option[...]
) that unexpectedly was fed a null value. Because of the async nature of DB operations and the fact those two happened almost at the same time, I was wrongly led to above assumptions when debugging. To be fair, that error stack trace wasn't too helpful either.
I'll just leave this question for posteriority, so people investating similar issues can learn from my mistakes.