6

文字列としてキャストせずに、Anorm を使用して PostgreSQL 9.3 データベースのデータ型フィールドにJsObjectaを渡すにはどうすればよいですか?json

次のような PostgreSQL 9.3 テーブルがあるとします。

create table profiles
(
  id serial primary key,
  profile json null
);

Play 2.2 では、このテストは成功します:

package helpers

import anorm._
import org.specs2.mutable._
import org.specs2.runner._
import org.junit.runner._
import play.api.db.DB
import play.api.libs.json._
import play.api.test._

@RunWith(classOf[JUnitRunner])
class AnormTest extends Specification {
  "AnormTest" should {
    "insert a JSON object" in new WithApplication {
      val profile = Json.obj("language" -> "en")
      val sql = SQL("insert into profiles (profile) values (CAST({profile} AS json))")
        .on("profile" -> profile.toString)
      DB.withConnection { implicit c => sql.execute() }
    }
  }
}

しかし、これらの行が変更された場合:

      val sql = SQL("insert into profiles (profile) values ({profile})")
        .on("profile" -> profile)

次のエラーが発生します。

org.postgresql.util.PSQLException: 
Can't infer the SQL type to use for an instance of play.api.libs.json.JsObject. 
Use setObject() with an explicit Types value to specify the type to use.

Anorm では通常、テキストの代わりに適切なデータ型 (たとえば、データ型UUIDの列のオブジェクト) を渡すため、SQL ステートメントでを文字列に変換してデータ型にキャストし直すuuidのは最適ではありません。JsObjectjson

この問題とその回避策の例については、Using PostgreSQL's native JSON support in Play Framework 2.1-RC1を参照してください。

データ型JsObjectとして直接渡すために、これを Anorm でどのように回避できますか?json

4

1 に答える 1

8

Play 2.4 以降では、値を直接指定する代わりに anorm.Object(value: org.postgresql.util.PGobject) クラスを使用します。

val pgObject = new org.postgresql.util.PGobject();
pgObject.setType("json");
pgObject.setValue(profile);
val sql = SQL("insert into profiles (profile) values ({profile})")
    .on("profile" -> anorm.Object(pgObject))
于 2014-09-10T19:33:37.117 に答える