Anorm Play2 не может работать на postgresql

Я обнаружил, что синтаксические анализаторы строки в play2 зависят от метаданных, возвращаемых драйвером jdbc.

Итак, во встроенном образце «zentasks», предоставленном play, я могу найти такой код:

object Project {
  val simple = {
    get[Pk[Long]]("project.id") ~
    get[String]("project.folder") ~
    get[String]("project.name") map {
      case id~folder~name => Project(id, folder, name)
    }
  }
}

Обратите внимание, что все поля имеютproject. префикс.

Это хорошо работает на базе данных h2, но не на postgresql. Если я использую portgresql, я должен написать это так:

object Project {
  val simple = {
    get[Pk[Long]]("id") ~
    get[String]("folder") ~
    get[String]("name") map {
      case id~folder~name => Project(id, folder, name)
    }
  }
}

Я спросилэто в Google Play группыи Гийом Борт сказал:

Да, если вы используете postgres, это, вероятно, причина. Драйвер postgresql jdbc не работает и не возвращает имена таблиц.

Если у драйвера postgresql jdbc действительно есть эта проблема, я думаю, что будет проблема для anorm:Если в двух таблицах есть поля с одинаковым именем, и я запрашиваю ихjoin, anorm не получит правильные значения, поскольку он не может узнать, какое имя принадлежит какой таблице.

Поэтому я пишу тест.

1. создавать таблицы на postgresql
create table a (
    id      text not null primary key,
    name    text not null
);

create table b (
    id      text not null primary key,
    name    text not null,
    a_id    text,
    foreign key(a_id) references a(id) on delete cascade
);
2. создавать анормальные модели
case class A(id: Pk[String] = NotAssigned, name: String)
case class B(id: Pk[String] = NotAssigned, name: String, aId: String)

object A {
  val simple = {
    get[Pk[String]]("id") ~
      get[String]("name") map {
        case id ~ name =>
          A(id, name)
      }
  }

  def create(a: A): A = {
    DB.withConnection { implicit connection =>
      val id = newId()
      SQL("""
          insert into a (id, name)
          values (
            {id}, {name}
          )
          """).on('id -> id, 'name -> a.name).executeUpdate()
      a.copy(id = Id(id))
    }
  }

  def findAll(): Seq[(A, B)] = {
    DB.withConnection { implicit conn =>
      SQL("""
          select a.*, b.* from a as a left join b as b on a.id=b.a_id
          """).as(A.simple ~ B.simple map {
        case a ~ b => a -> b
      } *)
    }
  }
}

object B {
  val simple = {
    get[Pk[String]]("id") ~
      get[String]("name") ~
      get[String]("a_id") map {
        case id ~ name ~ aId =>
          B(id, name, aId)
      }
  }

  def create(b: B): B = {
    DB.withConnection { implicit conneciton =>
      val id = UUID.randomUUID().toString
      SQL("""
          insert into b (id, name, a_id) 
          values (
          {id}, {name}, {aId}
          )
          """).on('id -> id, 'name -> b.name, 'aId -> b.aId).executeUpdate()
      b.copy(id = Id(id))
    }
  }
}
3. тестовые случаи с самыми большими
class ABTest extends DbSuite {

  "AB" should "get one-to-many" in {
    running(fakeApp) {
      val a = A.create(A(name = "AAA"))
      val b1 = B.create(B(name = "BBB1", aId = a.id.get))
      val b2 = B.create(B(name = "BBB2", aId = a.id.get))

      val ab = A.findAll()
      ab foreach {
        case (a, b) => {
          println("a: " + a)
          println("b: " + b)
        }
      }
    }
  }
}
4. выход
a: A(dbc52793-0f6f-4910-a954-940e508aab26,BBB1)
b: B(dbc52793-0f6f-4910-a954-940e508aab26,BBB1,4a66ebe7-536e-4bd5-b1bd-08f022650f1f)
a: A(d1bc8520-b4d1-40f1-af92-52b3bfe50e9f,BBB2)
b: B(d1bc8520-b4d1-40f1-af92-52b3bfe50e9f,BBB2,4a66ebe7-536e-4bd5-b1bd-08f022650f1f)

Вы можете видеть, что «а» имеют имя «BBB1 / BBB2», но не «AAA».

Я попытался переопределить парсеры с префиксами как:

 val simple = {
    get[Pk[String]]("a.id") ~
      get[String]("a.name") map {
        case id ~ name =>
          A(id, name)
      }
  }

Но он сообщит об ошибках, что они не могут найти указанные поля.

Это большая проблема анорм? Или я что-то пропустил?

Ответы на вопрос(1)

Ваш ответ на вопрос