I don't understand how to manage optional relationships when mapping tables to entities. For example, consider the following test:
test("left join"){
AppDB4Tests.database.withSession{
case class Supplier(id:Int,name:String)
case class Coffee(id:Int,supplierId:Int,name:String)
object Suppliers extends Table[Supplier]("SUPPLIER"){
def id = column[Int]("id", O.PrimaryKey)
def name = column[String]("name")
def * = id ~ name <>(Supplier, Supplier.unapply _)
}
object Coffees extends Table[Coffee]("COFFEE"){
def id = column[Int]("id", O.PrimaryKey)
def name = column[String]("name")
def supplierId = column[Int]("sup_id", O.NotNull)
def * = id ~supplierId~name <>(Coffee,Coffee.unapply _)
def fkSupplier = foreignKey("fk_supId", supplierId,Suppliers)(_.id)
}
(Suppliers.ddl ++ Coffees.ddl).create
Suppliers.insert(Supplier(1, "my supp"))
val query = for {
(s, c) <- Suppliers leftJoin Coffees /*on (_.id === _.supplierId)*/
} yield (s, c.name.orZero)
assert(query.list.length === 1)
val entityQuery = for {
(s, c) <- Suppliers leftJoin Coffees /*on (_.id === _.supplierId)*/
} yield (s, c)
assert(entityQuery.list.length === 1) //Fails!
}
}
The first query is ok but the second fails because of the previously mentioned 'Read NULL value for column COFFEE.id'.
If the query becomes :
val entityQuery = for {
(s, c) <- Suppliers leftJoin Coffees /*on (_.id === _.supplierId)*/
} yield (s, c.orZero)
Compilation fails:
error: could not find implicit value for evidence parameter of type scala.slick.lifted.TypeMapper[c.type]
} yield (s, c.orZero)
By the way, in 1.0.0-RC1, orZero is deprecated and getOrElse is recommended, but how to use it?
For example:
val query = for {
(s, c) <- Suppliers leftJoin Coffees /*on (_.id === _.supplierId)*/
} yield (s, c.name.getOrElse(""))
produces :
error: Cannot prove that Option[String] =:= String.
} yield (s, c.name.getOrElse(""))
and:
val entityQuery = for {
(s, c) <- Suppliers leftJoin Coffees /*on (_.id === _.supplierId)*/
} yield (s, c.getOrElse(Coffee(-1,-1,"")))
produces:
error: value getOrElse is not a member of object Coffees
} yield (s, c.getOrElse(Coffee(-1,-1,"")))