存储字节数组时,Scala Anorm Postgresql错误 [英] Scala Anorm Postgresql Error When Storing Byte Array
问题描述
我在Scala Playframework中有一个数据库表定义为
I have a database table in Scala Playframework defined as
CREATE TABLE account (
id SERIAL,
email TEXT NOT NULL,
buffer BYTEA NOT NULL,
PRIMARY KEY (id)
);
我正在使用协议缓冲区通过以下代码将对象序列化为字节数组
I am using a protocol buffer to serialize an object to a byte array with the following code
DB.withConnection{ implicit c=>
SQL("INSERT INTO device (buffer,secret) VALUES ({secret},{buffer})").on(
"secret"->device.getSecret(),
"buffer"->device.toByteArray()
).executeInsert()
}
device.toByteArray()
返回的类型是Array[Byte]
,应该与该列的数据库类型匹配.但是,执行代码后,我得到
The type returned by device.toByteArray()
is Array[Byte]
which should match the database type for that column. However upon executing the code I get
play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[PSQLException: ERROR: column "buffer" is of type bytea but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 44]]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:134) [play_2.9.1.jar:2.0.3]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115) [play_2.9.1.jar:2.0.3]
at akka.actor.Actor$class.apply(Actor.scala:318) [akka-actor.jar:2.0.2]
at play.core.ActionInvoker.apply(Invoker.scala:113) [play_2.9.1.jar:2.0.3]
at akka.actor.ActorCell.invoke(ActorCell.scala:626) [akka-actor.jar:2.0.2]
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197) [akka-actor.jar:2.0.2]
Caused by: org.postgresql.util.PSQLException: ERROR: column "buffer" is of type bytea but expression is of type character varying
推荐答案
查看 Postgres文档,您似乎需要添加一个处理程序,以使用setBytes
而不是当前代码要求的setObject
正确存储Array[Byte]
.
Looking at the anorm source and the Postgres docs, it looks like you'll need to add a handler for storing Array[Byte]
properly using setBytes
instead of setObject
, which the current code calls for.
我将在框架中的anyParameter中扩展匹配以读取
I'd extend the match in anyParameter in the framework to read
value match {
case Some(bd: java.math.BigDecimal) => stmt.setBigDecimal(index, bd)
case Some(b: Array[Byte]) => stmt.setBytes(index, b)
case Some(o) => stmt.setObject(index, o)
// ...
并添加
implicit val byteArrayToStatement = new ToStatement[Array[Byte]] {
def set(s: java.sql.PreparedStatement, index: Int, aValue: Array[Byte]): Unit = setAny(index, aValue, s)
}
您可能还可以通过在这里工作的类型类魔术来在框架之外执行此操作,但是我现在没有时间弄清楚这一点.
You should potentially be able to do this outside the framework as well through the type class magic at work here, but I don't have time to figure that out right now.
这篇关于存储字节数组时,Scala Anorm Postgresql错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!