4

The data column of PostgreSQL table my_table is of format jsonb. I would like to insert a Scala JsObject (or JsValue), but don't know how to do it!

The following code does not compile, because the on function expects json to be a String:

  def add(json: JsObject): Option[Long] = {
    DB.withConnection {
      implicit c =>

        val query = """
             insert into my_table(data)
        values({data});"""

        SQL(query).on(
          "data" -> json
        ).executeInsert()
    }
  }

What is the solution?

5
  • possible duplicate of PostgreSQL jsonb, `?` and JDBC Commented Jan 21, 2015 at 8:52
  • A specific parameter conversion can be plugged to prepare part of SQL statement and pass JSON values. Commented Jan 21, 2015 at 8:55
  • @applicius It's not a duplicate of PostgreSQL jsonb, '?' and JDBC. My question is about an insert statement. Commented Jan 21, 2015 at 12:53
  • @Blackbird do you solve this problem ? Commented May 9, 2017 at 13:36
  • @mgosk No I didn't solve it. Commented May 11, 2017 at 6:11

3 Answers 3

3

Use ::jsonb tag at the end of a value. eg.

//my scala variables

val jsonDescription: String = "{\"name\":\"ksulr\"}"
val age = 15

//my insert statement
val sql = "INSERT into person(json_description,age) VALUES(?::jsonb,?)"

//prepared statement
val statement = conn.prepareStatement(sql)

//insert values into the sql statement
statement.setString(1,jsonDescription)
statement.setInt(2,age)

statement.executeUpdate()

This will work. It worked for me. Thats how I inserted into a postgres db column of type jsonb.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer! It probably works, but it's not using Anorm.
1

Borrowing from @KJay_wer, we can use ::jsonb tag with Scala Anorm (Play Framework) too, and convert your JsObject (or other JsValue) into String:

def add(json: JsObject): Option[Long] = {
    DB.withConnection {
      implicit c =>

        val query = """
             insert into my_table (data)
             values ({data}::jsonb);
             """.stripMargin

        SQL(query).on(
          "data" -> json.toString
        ).executeInsert()
    }
  }

5 Comments

just tested it with ::json
Sounds like a good solution, thanks! But it's been so long ago, I unfortunately cannot verify it. I've upvoted it though :)
I tested ::json with all the tags on the question and it worked like a charm!
Is it ::json, or ::jsonb as in your code example?
In the code example above I put ::jsonb to match the original question; I used ::json on my use case, which was slightly different. I assume the solution works for your original case too.
0

You can use ToStatement converter object:

def add(json: JsObject): Option[Long] = {
   DB.withConnection { implicit c =>       
      val query = """insert into my_table(data) values(${data});"""
      SQL(query).executeInsert()
   }
}

implicit object jsObjectStatement extends ToStatement[JsObject] {
    override def set(s: PreparedStatement, index: Int, v: JsObject): Unit = {
      val jsonObject = new PGobject()
      jsonObject.setType("json")
      jsonObject.setValue(Json.stringify(v))
      s.setObject(index, jsonObject)
    }
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.