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.
source to share
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))
}
}
}
source to share