Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Anorm throw a TypeDoesNotMatch exception when inserting a Primary Key as Text?

I have a table in Postgres 9.4 that has email address as the Primary Key. Using Anorm, I then carry out the following

 DB.withConnection { implicit connection =>
  SQL"insert into member_login_email(email, password) values ($email, $password)".executeInsert()
}

When this is executed, the correct values are entered into the table, but a TypeDoesNotMatch runtime exception is thrown:

    at play.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.7.jar:2.3.7]
    at play.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.7.jar:2.3.7]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.7.jar:2.3.7]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.7.jar:2.3.7]
    at scala.Option.map(Option.scala:145) [scala-library-2.11.1.jar:na]
Caused by: java.lang.RuntimeException: TypeDoesNotMatch(Cannot convert [email protected]: class java.lang.String to Long for column ColumnName(member_login_email.email,Some(email)))
    at scala.sys.package$.error(package.scala:27) ~[scala-library-2.11.1.jar:na]
    at anorm.Sql$.anorm$Sql$$as(Anorm.scala:472) ~[anorm_2.11-2.3.7.jar:2.3.7]
    at anorm.Sql$class.executeInsert(Anorm.scala:350) ~[anorm_2.11-2.3.7.jar:2.3.7]
    at anorm.SimpleSql.executeInsert(Anorm.scala:190) ~[anorm_2.11-2.3.7.jar:2.3.7]
    at repository.MemberLoginEmailRepository$$anonfun$create$1.apply(MemberLoginEmailRepository.scala:17) ~[classes/:na]

It seems that Anorm is expecting Primary Keys to be of type Long. Is there anyway of getting Anorm to accept a Primary Key of type Text without throwing an exception?

I've looked at the source code for Anorm but have been struggling to see where this is actually happening.

like image 985
Arthur Avatar asked Sep 08 '25 08:09

Arthur


1 Answers

By default, executeInsert() is using a ResultSetParser[Option[Long]] to parse the primary key returned from the database. As seen from the scaladocs:

def executeInsert[A](generatedKeysParser: ResultSetParser[A] = SqlParser.scalar[Long].singleOpt)

To make this work with a String primary key, you would use this instead:

executeInsert(SqlParser.scalar[String].singleOpt)

This will return an Option[String].

like image 158
Michael Zajac Avatar answered Sep 10 '25 11:09

Michael Zajac