From 5cfb80703bec835e1a145b991a08cc0a7ebabf94 Mon Sep 17 00:00:00 2001 From: alexshabal Date: Thu, 19 Sep 2024 22:25:17 +0300 Subject: [PATCH] Fix UnexpectedNullValueInColumn exception in caseClassParser if first parameter in case class is optional (#98) Co-authored-by: Aleksandr Shabalin --- .../com/ringcentral/cassandra4io/cql/CqlSuite.scala | 7 +++++++ .../com/ringcentral/cassandra4io/cql/Reads.scala | 12 ++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/it/scala/com/ringcentral/cassandra4io/cql/CqlSuite.scala b/src/it/scala/com/ringcentral/cassandra4io/cql/CqlSuite.scala index face0fd..a12a19e 100644 --- a/src/it/scala/com/ringcentral/cassandra4io/cql/CqlSuite.scala +++ b/src/it/scala/com/ringcentral/cassandra4io/cql/CqlSuite.scala @@ -399,6 +399,13 @@ trait CqlSuite { } yield expect(row.isDefined && row.get.data.isEmpty) } + test("decoding from null should return None for optional case class first parameter") { session => + case class OptDataReverse(data: Option[String], id: Long) + for { + row <- cql"select data, id FROM cassandra4io.test_data WHERE id = 0".as[OptDataReverse].selectFirst(session) + } yield expect(row.isDefined && row.get.data.isEmpty) + } + test("decoding from null should raise error String field in case class") { session => for { result <- cql"select id, data FROM cassandra4io.test_data WHERE id = 0".as[Data].selectFirst(session).attempt diff --git a/src/main/scala/com/ringcentral/cassandra4io/cql/Reads.scala b/src/main/scala/com/ringcentral/cassandra4io/cql/Reads.scala index 29de574..e197ebe 100644 --- a/src/main/scala/com/ringcentral/cassandra4io/cql/Reads.scala +++ b/src/main/scala/com/ringcentral/cassandra4io/cql/Reads.scala @@ -121,8 +121,12 @@ trait ReadsLowestPriority { implicit def caseClassParser[A, R <: HList](implicit gen: Generic[A] { type Repr = R }, reprParser: Reads[R] - ): Reads[A] = (row: Row, index: Int) => { - val rep = reprParser.read(row, index) - gen.from(rep) - } + ): Reads[A] = + new Reads[A] { + override def readNullable(row: Row, index: Int): A = { + val rep = reprParser.read(row, index) + gen.from(rep) + } + override def read(row: Row, index: Int): A = readNullable(row, index) + } }