Quill cassandra,找不到用户定义数据类型的编解码器错误
Quill cassandra, codec not found error for an user defined data type
我在我的 "play-scala" 项目中使用 quill 作为 cassandra 驱动程序。
我有一个具有以下结构的 table -
CREATE TABLE user_data (
id int,
name string,
addresses list<frozen<dwelltimebd>>
PRIMARY KEY ((id, name))
)
其中 ADDRESS 是用户定义的数据类型,如此处所述 -
CREATE TYPE ADDRESS (
city string,
country string
);
为访问此 table 中的数据而编写的代码是这样的 -
object UserTable {
case class addresses(city: String, country: String)
case class userData ( id :Int, name :String, addresses : Seq[addresses])
lazy val ctx = new CassandraAsyncContext[SnakeCase]("user")
import ctx._
implicit val seqAddressDecoder: Decoder[Seq[addresses]] =
decoder[Seq[addresses]] { (row: Row) =>
(index) =>
row.getList(index, classOf[addresses]).asScala
}
implicit val seqAddressesEncoder: Encoder[Seq[addresses]] =
encoder[Seq[addresses]] { (row: BoundStatement) =>(idx, lista) =>
row.setList(idx, lista.toList.asJava, classOf[addresses])
}
def getUserData(id: Int, name: String) = {
val getAllDetail = quote {
query[userData].filter(p => p.id == lift(id) && p.name == lift(name))
}
val result: List[userData] = Await.result(ctx.run(
getAllDetail
), Duration.Inf)
result
}
}
在 运行 上面的代码中收到以下错误,-
play.api.UnexpectedException: Unexpected exception[CodecNotFoundException: Codec not found for requested operation: [frozen<user.addresses> <-> models.databaseModels.UserTable$addresses]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:289)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:220)
at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$$anonfun$apply.applyOrElse(PlayRequestHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$$anonfun$apply.applyOrElse(PlayRequestHandler.scala:99)
at scala.concurrent.Future$$anonfun$recoverWith.apply(Future.scala:346)
at scala.concurrent.Future$$anonfun$recoverWith.apply(Future.scala:345)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [frozen<user.addresses> <-> models.databaseModels.UserTable$addresses]
at com.datastax.driver.core.CodecRegistry.notFound(CodecRegistry.java:679)
at com.datastax.driver.core.CodecRegistry.createCodec(CodecRegistry.java:526)
at com.datastax.driver.core.CodecRegistry.findCodec(CodecRegistry.java:506)
at com.datastax.driver.core.CodecRegistry.maybeCreateCodec(CodecRegistry.java:558)
at com.datastax.driver.core.CodecRegistry.createCodec(CodecRegistry.java:524)
at com.datastax.driver.core.CodecRegistry.findCodec(CodecRegistry.java:506)
at com.datastax.driver.core.CodecRegistry.access0(CodecRegistry.java:140)
at com.datastax.driver.core.CodecRegistry$TypeCodecCacheLoader.load(CodecRegistry.java:211)
at com.datastax.driver.core.CodecRegistry$TypeCodecCacheLoader.load(CodecRegistry.java:208)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3542)
无法解决问题,我收到的一些指示是,
I need to first create Java TypeCodec and register it with the cluster. Then also need to implement row-codec for quill just to make it compile.
来自 this post
无法理解如何去做,这方面的任何帮助都会有所帮助。
这对我有用:
来自 Datastax 文档:
By default, the driver maps user-defined type values to UDTValue
instances.
对于解码器,请尝试以下方式:
import scala.collection.JavaConverters._
implicit val addressListDecoder: Decoder[List[Address]] = decoder(
(index, row) =>
row.getList(index, classOf[UDTValue]).asScala.toList.map { a =>
Address(a.getString("city"), a.getString("country"))
}
)
这行不通:(但可能是我不够努力)
理论上,您还可以定义自定义编解码器,扩展 Quill 的 CassandraAsyncContext
(或任何可用上下文)以获得 Cluster
对象,然后注册自定义编解码器:
def registerCodecs(cluster: Cluster): Unit = {
val codecRegistry = cluster.getConfiguration.getCodecRegistry
codecRegistry.register(new LocalDateTimeCodec) //just for example
}
您可以从现有的 "basic" 编解码器中编写编解码器。
我在我的 "play-scala" 项目中使用 quill 作为 cassandra 驱动程序。 我有一个具有以下结构的 table -
CREATE TABLE user_data (
id int,
name string,
addresses list<frozen<dwelltimebd>>
PRIMARY KEY ((id, name))
)
其中 ADDRESS 是用户定义的数据类型,如此处所述 -
CREATE TYPE ADDRESS (
city string,
country string
);
为访问此 table 中的数据而编写的代码是这样的 -
object UserTable {
case class addresses(city: String, country: String)
case class userData ( id :Int, name :String, addresses : Seq[addresses])
lazy val ctx = new CassandraAsyncContext[SnakeCase]("user")
import ctx._
implicit val seqAddressDecoder: Decoder[Seq[addresses]] =
decoder[Seq[addresses]] { (row: Row) =>
(index) =>
row.getList(index, classOf[addresses]).asScala
}
implicit val seqAddressesEncoder: Encoder[Seq[addresses]] =
encoder[Seq[addresses]] { (row: BoundStatement) =>(idx, lista) =>
row.setList(idx, lista.toList.asJava, classOf[addresses])
}
def getUserData(id: Int, name: String) = {
val getAllDetail = quote {
query[userData].filter(p => p.id == lift(id) && p.name == lift(name))
}
val result: List[userData] = Await.result(ctx.run(
getAllDetail
), Duration.Inf)
result
}
}
在 运行 上面的代码中收到以下错误,-
play.api.UnexpectedException: Unexpected exception[CodecNotFoundException: Codec not found for requested operation: [frozen<user.addresses> <-> models.databaseModels.UserTable$addresses]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:289)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:220)
at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$$anonfun$apply.applyOrElse(PlayRequestHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$$anonfun$apply.applyOrElse(PlayRequestHandler.scala:99)
at scala.concurrent.Future$$anonfun$recoverWith.apply(Future.scala:346)
at scala.concurrent.Future$$anonfun$recoverWith.apply(Future.scala:345)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [frozen<user.addresses> <-> models.databaseModels.UserTable$addresses]
at com.datastax.driver.core.CodecRegistry.notFound(CodecRegistry.java:679)
at com.datastax.driver.core.CodecRegistry.createCodec(CodecRegistry.java:526)
at com.datastax.driver.core.CodecRegistry.findCodec(CodecRegistry.java:506)
at com.datastax.driver.core.CodecRegistry.maybeCreateCodec(CodecRegistry.java:558)
at com.datastax.driver.core.CodecRegistry.createCodec(CodecRegistry.java:524)
at com.datastax.driver.core.CodecRegistry.findCodec(CodecRegistry.java:506)
at com.datastax.driver.core.CodecRegistry.access0(CodecRegistry.java:140)
at com.datastax.driver.core.CodecRegistry$TypeCodecCacheLoader.load(CodecRegistry.java:211)
at com.datastax.driver.core.CodecRegistry$TypeCodecCacheLoader.load(CodecRegistry.java:208)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3542)
无法解决问题,我收到的一些指示是,
I need to first create Java TypeCodec and register it with the cluster. Then also need to implement row-codec for quill just to make it compile.
来自 this post
无法理解如何去做,这方面的任何帮助都会有所帮助。
这对我有用:
来自 Datastax 文档:
By default, the driver maps user-defined type values to UDTValue instances.
对于解码器,请尝试以下方式:
import scala.collection.JavaConverters._
implicit val addressListDecoder: Decoder[List[Address]] = decoder(
(index, row) =>
row.getList(index, classOf[UDTValue]).asScala.toList.map { a =>
Address(a.getString("city"), a.getString("country"))
}
)
这行不通:(但可能是我不够努力)
理论上,您还可以定义自定义编解码器,扩展 Quill 的 CassandraAsyncContext
(或任何可用上下文)以获得 Cluster
对象,然后注册自定义编解码器:
def registerCodecs(cluster: Cluster): Unit = {
val codecRegistry = cluster.getConfiguration.getCodecRegistry
codecRegistry.register(new LocalDateTimeCodec) //just for example
}
您可以从现有的 "basic" 编解码器中编写编解码器。