skinny-framework / skinny-framework

:monorail: "Scala on Rails" - A full-stack web app framework for rapid development in Scala

Home Page:https://skinny-framework.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UUID failed with postgresql

chakming opened this issue · comments

I'm now trying to write a simple integration test: insert a Member with name and UUID as primary key.
It works perfectly in h2 memory database, but not working for Postgresql, which having the following error:

12:01:53.368 [ScalaTest-run-running-MemberSpec] ERROR s.StatementExecutor$$anon$1 - SQL execution failed (Reason: ERROR: column "uuid" is of type uuid but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 45):

   insert into member (name, uuid) values ('Skinny', '60a3193b-ac24-44f7-8637-ab0c71833189')

12:01:53.402 [ScalaTest-run-running-MemberSpec] DEBUG scalikejdbc.DB - A Connection is closed.

I've created a repo to demonstrate the issue:
https://github.com/chakming/skinny-orm-postgresql-UUID

Any clue?

When you choose useExternalIdGenerator, you must pass primary key value generated by your hand here: https://github.com/chakming/skinny-orm-postgresql-UUID/blob/fe834db21bd9c5dd6538fab99fe71671fad56fb3/src/test/scala/MemberSpec.scala#L22-L24

@seratch I've tried to pass manually but still the same error
chakming/skinny-orm-postgresql-UUID@36e2ef7


13:17:58.817 [ScalaTest-run-running-MemberSpec] ERROR s.StatementExecutor$$anon$1 - SQL execution failed (Reason: ERROR: column "uuid" is of type uuid but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 41):

   insert into member (uuid, name) values ('6c05da7f-58ed-4368-938b-536b1d18a594', 'Skinny')

13:17:58.825 [ScalaTest-run-running-MemberSpec] DEBUG scalikejdbc.DB - A Connection is closed.

According to the stackoverflow Q&A, just sending String value won't work for you.

@seratch Thanks for prompt reply. I'm not sure if you mean passing the UUID object instead of turning it into String?
Still the same error:
chakming/skinny-orm-postgresql-UUID@e52f4a7

17:14:44.384 [ScalaTest-run-running-MemberSpec] ERROR s.StatementExecutor$$anon$1 - SQL execution failed (Reason: ERROR: column "uuid" is of type uuid but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 41):

   insert into member (uuid, name) values ('ec74bbd7-9085-4fa9-aed3-077a8eb1d8bf', 'Skinny')

17:14:44.414 [ScalaTest-run-running-MemberSpec] DEBUG scalikejdbc.DB - A Connection is closed.

Sorry, I've forgetten to paste the stackoverflow link. I understand passing UUID asis doesn't work. Can this topic help you? http://stackoverflow.com/questions/30985604/how-to-insert-value-of-uuid

Thanks, but no luck! I've tried different method but I'm not sure if anything related to SQLSyntax/SQLInterpolationString interpret UUID object wrongly (Or do i need to have custom ParameterBinder & TypeBinder?).

failed:

val memberId: UUID = UUID.fromString("a142f83f-14e8-43be-8861-3fcd11abf08e")
sql"insert into member (uuid, name) values ("${memberId}", 'Skinny')".execute().apply()

success:

val memberId: UUID = UUID.fromString("a142f83f-14e8-43be-8861-3fcd11abf08e")
sql"insert into member (uuid, name) values (${memberId.toString}::uuid, 'Skinny')".execute().apply()

And I've tried with createWithNamedValues to create records, but none of case success.

Is there any hint I can use skinnyORM's createWith methods? And this looks like may have SQL injection vulnerability - scalikejdbc/scalikejdbc#116 ?

One interesting thing is: when I try query existing record using findAll, it's able to get those record's UUID, while calling Member.findById(existingUUID) would cause following error

22:25:03.917 [ScalaTest-run-running-MemberSpec] ERROR s.StatementExecutor$$anon$1 - SQL execution failed (Reason: ERROR: operator does not exist: uuid = character varying
  Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
  Position: 97):

   select m.uuid as u_on_m, m.name as n_on_m, m.deleted_at as da_on_m from member m where m.uuid = 'a142f83f-14e8-43be-8861-3fcd11abf08e' and ( m.deleted_at is null)

22:25:03.926 [ScalaTest-run-running-MemberSpec] DEBUG scalikejdbc.DB - A Connection is closed.