Cassandra CodecNotFoundException:找不到请求的操作的编解码器

时间:2017-12-27 17:44:02

标签: java cassandra datastax cassandra-3.0

我有一个枚举字段,我想映射到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就好了。这是模型类的片段

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创建表的方法

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)

我做错了什么?

2 个答案:

答案 0 :(得分:3)

EnumOrdinalCodec用于在int&lt; - &gt;之间进行映射。仅限枚举。由于您的Enum基于字符串,因此请改用EnumNameCodec类。这两个编解码器类的Javadoc如下所示。希望它有所帮助。

<强> EnumNameCodec

  

将Enum实例序列化为CQL varchars表示的编解码器   他们的程序名称由Enum.name()返回。

<强> EnumOrdinalCodec

  

将Enum实例序列化为代表其的CQL注入的编解码器   Enum.ordinal()返回的序数值。

链接到Javadoc

答案 1 :(得分:0)

如下更改您的代码:

/* 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;
    }
}