What's the correct way to insert / update BLOBs using Play 2.3?

I am running a Play server that has a MySQL database. One of his tables has BLOB

. In game 2.2, before any explicit ParameterValue

business introduced in 2.3, I was able to read / write by simply typing Array[Byte]

into my query:

val foo: Array[Byte] = ???  // Doesn't matter.
SQL("update my_table set the_blob = {foo} where id = {id}").on('foo -> foo, 'id -> id).executeUpdate()

      

It doesn't work anymore. It will complain at compile time:

type mismatch;                                                                  
  found   : (Symbol, Array[Byte])
  required: anorm.NamedParameter

      

It seemed like Anorm didn't know how to convert Array[Byte]

, so in my stupidity I wrote:

// Now everything will work perfectly and I can get back to my day.
implicit def byteArrayToParameter(ba: Array[Byte]): ParameterValue = {
  ba
}

      

I had no problems at first, but eventually I noticed that any attempt to write to a table with BLOB

:

  • Hang up your browser.
  • Cause. Replay java streams to hang any cpu cores they can find.
  • Never fill out an entry.

A lot of debugging took me back to the function implicit

above. The logging of the messages showed that this transformation was called over and over in an infinite loop.

Question: How to properly handle BLOB

with Anorm?

(or in general)

Question . How to ensure correct conversion instances for types that cannot be automatically converted to ParameterValue

?

Thank.

+3


source to share


1 answer


Others seem to have had similar problems, particularly in the area of ​​looking for any documentation on how to write these type mappings. My experience with Play is generally negative when it comes to discovering documentation.

The solution is this: borrowed from Grokbase thread and modified for clarity:



import java.sql.PreparedStatement

// Can't have top-level implicit objects, so we need a wrapper.
object foo {
  implicit object byteArrayToStatement extends ToStatement[Array[Byte]] {
    def set(s: PreparedStatement, i: Int, array: Array[Byte]): Unit = {
      s.setBlob(i, new javax.sql.rowset.serial.SerialBlob(array))
    } 
  }
}

      

+2


source







All Articles