2013-10-25 2 views
6

Как передать JsObject в поле типа данных json в базе данных PostgreSQL 9.3 с помощью Anorm без необходимости использовать его как строку?Вставка объектов Json в поля json PostgreSQL с помощью Anorm

Учитывая 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 объекта для столбца типа uuid данных), это не является оптимальным того, чтобы преобразовать JsObject в строку и бросьте его обратно в json тип данных в операторе SQL.

Для примера этой проблемы и ее обходного пути обратитесь к Using PostgreSQL's native JSON support in Play Framework 2.1-RC1.

Как этого можно избежать с помощью Anorm для передачи JsObject непосредственно в качестве типа данных json?

ответ

8

Для воспроизведения 2.4 и выше использовать anorm.Object (значение: 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)) 
Смежные вопросы