Play2的anorm不能在postgresql上工作
我发现play2的动画的行解析器取决于jdbc驱动程序返回的元数据。
所以在播放中提供的内置示例“zentasks”中,我可以找到这样的代码: 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) } } } 请注意,这些字段都有一个项目。字首。 它在h2数据库上运行良好,但不适用于postgresql。如果我使用portgresql,我应该写成: object Project { val simple = { get[Pk[Long]]("id") ~ get[String]("folder") ~ get[String]("name") map { case id~folder~name => Project(id,name) } } } 我问过this in play’s google group,而纪尧姆博特说:
如果postgresql的jdbc驱动程序真的有这个问题,我认为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.创建anorm模型 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,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) 您可以看到“a”的名称为“BBB1 / BBB2”,但不是“AAA”。 我试图用前缀重新定义解析器: val simple = { get[Pk[String]]("a.id") ~ get[String]("a.name") map { case id ~ name => A(id,name) } } 但是它会报告他们找不到指定字段的错误。 这是一个很大的问题吗?还是我想念的东西?
最新的play2(RC3)已经通过检查元对象的类名来解决这个问题:
// HACK FOR POSTGRES if (meta.getClass.getName.startsWith("org.postgresql.")) { meta.asInstanceOf[{ def getBaseTableName(i: Int): String }].getBaseTableName(i) } else { meta.getTableName(i) } 但是要小心,如果你想使用它与p6spy,它不起作用,因为类的名称将是“com.p6spy ….”,而不是“org.postgresql ….”。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |