Cassandra CodecNotFoundException:找不到请求的操作的编解码器
Cassandra CodecNotFoundException: Codec not found for requested operation
我有一个枚举字段,我想映射到 cassandra 中的一个列
public enum MyEnum {
Aa,
Bb,
Cc,
}
这是我注册的方式
CodecRegistry myCodecRegistry = new CodecRegistry();
myCodecRegistry.register(new EnumOrdinalCodec<MyEnum>(MyEnum.class));
cluster = Cluster.builder().addContactPoint(cassandraHosts).withPort(cassandraPort).withCodecRegistry(myCodecRegistry).build();
我可以很好地连接到 cassandra。这是模型的片段 class
public class MyModel
{
@PartitionKey
@Column(name="id")
private String id;
@ClusteringColumn
@Column(name="name")
private String name = "";
@Column(name="enum")
private MyEnum enum;
public MyModel(String i, String n)
{
id=i;
name=n
enum=MyEnum.Aa;
}
}
这是我如何使用 CQL
创建 table
CREATE TABLE IF NOT EXISTS
tab
(
name varchar ,
id varchar,
enum varchar,
PRIMARY KEY ((id), name));
终于有了我的映射码
manager = new MappingManager(session);
mapper = manager.mapper(MyModel.class);
accessor = manager.createAccessor(MyAccessor.class);
这里是 MyAccessor
@Accessor
public interface MyAccessor{
@Query("SELECT * FROM case WHERE id=? and name=? ALLOW FILTERING;")
MyModel readByIdAndName(String id,String name);
}
所以当我尝试执行时
MyModel m = new MyModel("asdasf","qw");
mapper.save(m);
我得到
com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [varchar <-> my.pack.MyEnum]
at com.datastax.driver.core.exceptions.CodecNotFoundException.copy(CodecNotFoundException.java:56)
at com.datastax.driver.core.exceptions.CodecNotFoundException.copy(CodecNotFoundException.java:25)
at com.datastax.driver.mapping.DriverThrowables.propagateCause(DriverThrowables.java:41)
at com.datastax.driver.mapping.Mapper.save(Mapper.java:289)
我做错了什么?
EnumOrdinalCodec 仅用于 int <-> Enum 之间的映射。由于您的枚举基于字符串,因此请改用 EnumNameCodec
class。这两个编解码器的 Javadoc classes 如下所示。希望对你有帮助。
EnumNameCodec
A codec that serializes Enum instances as CQL varchars representing
their programmatic names as returned by Enum.name().
EnumOrdinalCodec
A codec that serializes Enum instances as CQL ints representing their
ordinal values as returned by Enum.ordinal().
Link 到 Javadoc
按如下方式更改您的代码:
/* This is not required
CodecRegistry myCodecRegistry = new CodecRegistry();
myCodecRegistry.register(new EnumOrdinalCodec<MyEnum>(MyEnum.class));
*/
cluster = Cluster
.builder()
.addContactPoint(cassandraHosts)
.withPort(cassandraPort)
.build();
class MyEnumCodec: EnumOrdinalCodec<MyEnum> { MyEnumCodec() { super(MyEnum.class) } }
public class MyModel
{
@PartitionKey
@Column(name="id")
private String id;
@ClusteringColumn
@Column(name="name")
private String name = "";
@Column(name="enum", codec = MyEnumCodec.class)
private MyEnum enum;
public MyModel(String i, String n)
{
id=i;
name=n
enum=MyEnum.Aa;
}
}
我有一个枚举字段,我想映射到 cassandra 中的一个列
public enum MyEnum {
Aa,
Bb,
Cc,
}
这是我注册的方式
CodecRegistry myCodecRegistry = new CodecRegistry();
myCodecRegistry.register(new EnumOrdinalCodec<MyEnum>(MyEnum.class));
cluster = Cluster.builder().addContactPoint(cassandraHosts).withPort(cassandraPort).withCodecRegistry(myCodecRegistry).build();
我可以很好地连接到 cassandra。这是模型的片段 class
public class MyModel
{
@PartitionKey
@Column(name="id")
private String id;
@ClusteringColumn
@Column(name="name")
private String name = "";
@Column(name="enum")
private MyEnum enum;
public MyModel(String i, String n)
{
id=i;
name=n
enum=MyEnum.Aa;
}
}
这是我如何使用 CQL
创建 tableCREATE TABLE IF NOT EXISTS
tab
(
name varchar ,
id varchar,
enum varchar,
PRIMARY KEY ((id), name));
终于有了我的映射码
manager = new MappingManager(session);
mapper = manager.mapper(MyModel.class);
accessor = manager.createAccessor(MyAccessor.class);
这里是 MyAccessor
@Accessor
public interface MyAccessor{
@Query("SELECT * FROM case WHERE id=? and name=? ALLOW FILTERING;")
MyModel readByIdAndName(String id,String name);
}
所以当我尝试执行时
MyModel m = new MyModel("asdasf","qw");
mapper.save(m);
我得到
com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [varchar <-> my.pack.MyEnum]
at com.datastax.driver.core.exceptions.CodecNotFoundException.copy(CodecNotFoundException.java:56)
at com.datastax.driver.core.exceptions.CodecNotFoundException.copy(CodecNotFoundException.java:25)
at com.datastax.driver.mapping.DriverThrowables.propagateCause(DriverThrowables.java:41)
at com.datastax.driver.mapping.Mapper.save(Mapper.java:289)
我做错了什么?
EnumOrdinalCodec 仅用于 int <-> Enum 之间的映射。由于您的枚举基于字符串,因此请改用 EnumNameCodec
class。这两个编解码器的 Javadoc classes 如下所示。希望对你有帮助。
EnumNameCodec
A codec that serializes Enum instances as CQL varchars representing their programmatic names as returned by Enum.name().
EnumOrdinalCodec
A codec that serializes Enum instances as CQL ints representing their ordinal values as returned by Enum.ordinal().
Link 到 Javadoc
按如下方式更改您的代码:
/* This is not required
CodecRegistry myCodecRegistry = new CodecRegistry();
myCodecRegistry.register(new EnumOrdinalCodec<MyEnum>(MyEnum.class));
*/
cluster = Cluster
.builder()
.addContactPoint(cassandraHosts)
.withPort(cassandraPort)
.build();
class MyEnumCodec: EnumOrdinalCodec<MyEnum> { MyEnumCodec() { super(MyEnum.class) } }
public class MyModel
{
@PartitionKey
@Column(name="id")
private String id;
@ClusteringColumn
@Column(name="name")
private String name = "";
@Column(name="enum", codec = MyEnumCodec.class)
private MyEnum enum;
public MyModel(String i, String n)
{
id=i;
name=n
enum=MyEnum.Aa;
}
}