Skip to content

ClassCastException when reading from column[List[Double]] of column type numeric[] #589

@TobiasPfeifer

Description

@TobiasPfeifer

slick-pg version: 0.20.3
slick version: 3.3.3

A table with a column of type numeric[] that is defined as column[List[Double]] will insert List[Double] for that column just fine. However, it will not read a List[Double] but a List[BigDecimal] at runtime.

This will result in a ClassCastException when trying to access the values of List[Double]:
ERROR: java.lang.ClassCastException: class java.math.BigDecimal cannot be cast to class java.lang.Double (java.math.BigDecimal and java.lang.Double are in module java.base of loader 'bootstrap')

create table test
(
    id                   serial primary key,
    test             numeric[]
);
case class Test(test: List[Double]) //the field test will be read as List[BigDecimal]

def id                  = column[Int]("id", O.PrimaryKey, O.AutoInc)
def test                  = column[List[Double]]("test")
    def * =
      (
        id.? ::
          test::
          HNil
      ).<>(applyTest, unapplyTest)


def applyTest(data: Option[Int] :: List[Double] :: HNil): Test = data match {
      data match {
        case _ :: list => Test(list)
      }
}

VPostgresProfile.api._ and VPostgresProfile is in scope:

trait VPostgresProfile
    extends ExPostgresProfile
    with PgArraySupport
    with PgDate2Support
    with PgRangeSupport
    with PgHStoreSupport {
  def pgjson = "jsonb"

  // Add back `capabilities.insertOrUpdate` to enable native `upsert` support; for postgres 9.5+
  override protected def computeCapabilities: Set[Capability] =
    super.computeCapabilities + slick.jdbc.JdbcCapabilities.insertOrUpdate

  override val api = VAPI

  object VAPI extends API with ArrayImplicits with DateTimeImplicits with RangeImplicits with HStoreImplicits {
    val strSimpleJdbcArrayListType: SimpleArrayJdbcType[String] = new SimpleArrayJdbcType[String]("text")
    val longSimpleJdbcArrayListType: SimpleArrayJdbcType[Long]  = new SimpleArrayJdbcType[Long]("bigint")
    val sqlTSSimpleJdbcArrayListType: SimpleArrayJdbcType[SQLTimestamp] =
      new SimpleArrayJdbcType[SQLTimestamp]("timestamp")

    implicit val strListTypeMapper: JdbcType[List[String]] =
      strSimpleJdbcArrayListType.to(_.toList)
  }
}

object VPostgresProfile extends VPostgresProfile

workaround:

def applyTest(data: Option[Int] :: List[Double] :: HNil): Test = data match {
      data match {
        case _ :: list => Test(list.asInstanceOf[List[java.math.BigDecimal]].map(_.doubleValue))
      }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions