i'm running play 2.3 and have no way to update ...
whil i'm trying to parse jsonb column i get the error play - Cannot invoke the action, eventually got an error: java.lang.RuntimeException: UnexpectedNullableFound(ColumnName(.sports,Some(sports)))
my code is :
case class Sport(
id: UUID,
name: Option[String]
)
implicit val SportWrites: Writes[Sport] = Json.writes[Sport]
implicit val SportReads: Reads[Sport] = (
(JsPath \ "f1").read[UUID] and
(JsPath \ "f2").readNullable[String]
)
case class Member(
id:UUID,
name:String,
sports: List[Sport]
)
def memberParser: RowParser[Member] = {
get[UUID]("member_id") ~
get[String]("name") ~
get[JsValue]("sports") map {
case(id ~ name ~ sports) => Member(
id, name
sports.validate[List[Sport]].getOrElse(List())
)
}
}
def getMember():List[Member] = DB.WithConnection{ implicit c =>
SQL("SELECT m.id, m.name, m.sports::json from member m ").as(memberParser.*)
}
|Sports| is a jsonb postgresql column, if i dont cast this column as ::json
i get a TypeDoesNotMatc
h error.
Json fields are named "f1", "f2", "f3"(...) because i have populated this column with data from another table with JSON_AGG(...
so it's postgresql naming.
also this function is working:
def getMemberWithSports():List[Member] = DB.withConnection{ implicit c =>
SQL("""
SELECT m.member_id, m.name,
json_agg(row_to_json(row(s.sport_id, s.name))) as sports
FROM rank_member m
LEFT JOIN member_sport ms ON m.member_id = ms.member_id
LEFT JOIN sport s ON ms.sport_id = s.sport_id
GROUP BY m.member_id, m.fullname
""").as(memberParser.*)
}
the only difference between the results of these two SQL commande (in getMember() & getMemberWithSport() ) is that with the first query i get nothing in sport will the second query (the one that work in play) return JSON populated with null values.
the only workaround i've found for the moment is by adding COALESCE to the SQL query as follow:
def getMember():List[Member] = DB.WithConnection{ implicit c =>
SQL("SELECT m.id, m.name, COALESCE(m.sports::json, '[]') as sports from member m ").as(memberParser.*)
}