2013-10-25 10 views
6

Jak mogę przekazać JsObject do pola typu danych json w bazie danych PostgreSQL 9.3 za pomocą Anorma bez konieczności przesyłania go jako ciąg?Wstawianie obiektów Json w polach jsonowych PostgreSQL za pomocą Anorma

Biorąc pod uwagę PostgreSQL 9.3 tabela takich jak:

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

z luzem 2.2, ten test się powiedzie:

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() } 
    } 
    } 
} 

Ale z tych linii zmieniło:

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

Daje to błąd:

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. 

Ponieważ z Anorm zwykle przechodzą odpowiednie typy danych zamiast tekstu (na przykład, UUID obiekt dla kolumny typu uuid danych), to nie jest optymalne konieczności konwertowania JsObject na łańcuch i wrzucił go z powrotem do json typ danych w instrukcji SQL.

Przykład tego problemu i sposób jego obejścia znajduje się pod adresem Using PostgreSQL's native JSON support in Play Framework 2.1-RC1.

Jak można tego uniknąć przy pomocy Anorma, aby przekazać JsObject bezpośrednio jako typ danych json?

Odpowiedz

8

do sztuki 2.4 i użyć anorm.Object (o wartości org.postgresql.util.PGobject) klasy, a wartości bezpośrednio:

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))