com.datastax.driver.core.exceptions.CodecNotFoundException:找不到请求操作的编解码器:[int <-> java.lang.Long]

com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [int <-> java.lang.Long]

编写了这个简单的 Phantom DSL 代码

case class FooRow(id: Long, dt: DateTime, et: Long, rid: Option[Long], d: Option[String] = None)
class FooTable extends CassandraTable[FooTable, FooRow] {
   object id extends LongColumn(this) with PartitionKey[Long]
   object dt extends DateTimeColumn(this) with PartitionKey[DateTime]
   object et extends LongColumn(this) with PartitionKey[Long]
   object rid extends OptionalLongColumn(this)
   object d extends OptionalStringColumn(this)
   override def fromRow(r: Row): FooRow = {
      FooRow(
         id(r),
         dt(r),
         et(r),
         rid(r),
         d(r)
      )
   }
}

当我尝试插入一行时。使用此代码

   def put(data: FooRow) : ResultSet = {
      val query = insert
         .value(_.id, data.id)
         .value(_.dt, data.dt)
         .value(_.rid, data.rid)
         .value(_.d, data.d)
         .value(_.et, data.et)
      query.consistencyLevel_=(ConsistencyLevel.QUORUM)
      Await.result(query.future(), awaitConfiguration.awaitTimeoutValue seconds)
   }

我收到一个错误

[info] - should be able to retrieve all history records by respondent id *** FAILED ***
[info]   com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [int <-> java.lang.Long]
[info]   at com.datastax.driver.core.CodecRegistry.notFound(CodecRegistry.java:679)
[info]   at com.datastax.driver.core.CodecRegistry.createCodec(CodecRegistry.java:526)
[info]   at com.datastax.driver.core.CodecRegistry.findCodec(CodecRegistry.java:506)
[info]   at com.datastax.driver.core.CodecRegistry.access0(CodecRegistry.java:140)
[info]   at com.datastax.driver.core.CodecRegistry$TypeCodecCacheLoader.load(CodecRegistry.java:211)
[info]   at com.datastax.driver.core.CodecRegistry$TypeCodecCacheLoader.load(CodecRegistry.java:208)
[info]   at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3542)
[info]   at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2323)
[info]   at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2286)
[info]   at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2201)
[info]   at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
[info]   at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3957)
[info]   at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4875)
[info]   at com.datastax.driver.core.CodecRegistry.lookupCodec(CodecRegistry.java:480)
[info]   at com.datastax.driver.core.CodecRegistry.codecFor(CodecRegistry.java:448)
[info]   at com.datastax.driver.core.CodecRegistry.codecFor(CodecRegistry.java:430)
[info]   at com.datastax.driver.core.AbstractGettableByIndexData.codecFor(AbstractGettableByIndexData.java:69)
[info]   at com.datastax.driver.core.AbstractGettableByIndexData.getLong(AbstractGettableByIndexData.java:152)
[info]   at com.datastax.driver.core.AbstractGettableData.getLong(AbstractGettableData.java:26)
[info]   at com.datastax.driver.core.AbstractGettableData.getLong(AbstractGettableData.java:95)
[info]   at com.websudos.phantom.builder.primitives.DefaultPrimitives$LongPrimitive$$anonfun$fromRow.apply(Primitive.scala:187)
[info]   at com.websudos.phantom.builder.primitives.DefaultPrimitives$LongPrimitive$$anonfun$fromRow.apply(Primitive.scala:187)
[info]   at com.websudos.phantom.builder.primitives.Primitive$$anonfun$nullCheck.apply(Primitive.scala:69)
[info]   at scala.util.Try$.apply(Try.scala:192)
[info]   at com.websudos.phantom.builder.primitives.Primitive.nullCheck(Primitive.scala:69)
[info]   at com.websudos.phantom.builder.primitives.DefaultPrimitives$LongPrimitive$.fromRow(Primitive.scala:187)
[info]   at com.websudos.phantom.column.PrimitiveColumn.optional(PrimitiveColumn.scala:52)
[info]   at com.websudos.phantom.column.Column.apply(Column.scala:42)
[info]   at com.abhi.FooTable.fromRow(FooService.scala:27)

最令人困惑的是,如果您查看上面的代码,这里绝对没有任何 Int 。

根据堆栈跟踪,错误发生在行

et(r),

我唯一能想到的是你的 Cassandra 模式不是用 phantom 创建的,而且在你的数据库中,列的类型与 phantom 推断为有效的不同。

phantom 中的 longdatetime 列都被转换为 Cassandra 中的 bigint 类型,因此您需要确保数据库中的模式与之匹配。在我看来,您的数据库列之一是 int 而不是 long,因此当驱动程序尝试解析记录时,它会崩溃。这也意味着您没有使用自动模式生成,而 phantom 可以开箱即用。阅读 this 了解更多详情。

此外,题外话,在较新版本的 phantom 中,fromRowput 方法都是宏派生的,因此您实际上不需要手动输入它们。所以在 phantom 2.7.3 中我希望你的代码看起来像这样:

import com.outworkers.phantom.dsl._

case class FooRow(
  id: Long,
  dt: DateTime,
  et: Long,
  rid: Option[Long],
  d: Option[String] = None
)

abstract class FooTable extends CassandraTable[FooTable, FooRow] with RootConnector {
   object id extends LongColumn(this) with PartitionKey
   object dt extends DateTimeColumn(this) with PartitionKey
   object et extends LongColumn(this) with PartitionKey
   object rid extends OptionalLongColumn(this)
   object d extends OptionalStringColumn(this)

   def put(data: FooRow): ResultSet = {

     Await.result(
       store(data).consistencyLevel_=(ConsistencyLevel.QUORUM).future(),
       awaitConfiguration.awaitTimeoutValue seconds
     )

   }
}