Cassandra CodecNotFoundException: Codec not found for requested operation

淺唱寂寞╮ 提交于 2019-12-24 09:25:10

问题


I have an enum field that i want to map to a column in cassandra

public enum MyEnum {
    Aa,
    Bb,
    Cc,
}

and here is how i registered it

CodecRegistry myCodecRegistry = new CodecRegistry();
             myCodecRegistry.register(new EnumOrdinalCodec<MyEnum>(MyEnum.class));

            cluster = Cluster.builder().addContactPoint(cassandraHosts).withPort(cassandraPort).withCodecRegistry(myCodecRegistry).build();

i am able to connect to cassandra just fine. Here is a snippet of the model 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;
    }
}

and here is how i created the table using CQL

CREATE TABLE IF NOT EXISTS 
tab 
    (
        name varchar ,
        id varchar, 
        enum varchar, 
        PRIMARY KEY ((id), name));

finally, i have my mapping code

    manager = new MappingManager(session);
    mapper = manager.mapper(MyModel.class);
    accessor = manager.createAccessor(MyAccessor.class);

and here is the MyAccessor

@Accessor
public interface MyAccessor{

    @Query("SELECT * FROM case WHERE id=? and name=? ALLOW FILTERING;")
    MyModel readByIdAndName(String id,String name);
}

so when i try to execute

MyModel m = new MyModel("asdasf","qw");
mapper.save(m);

i get

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)

what am i doing wrong?


回答1:


EnumOrdinalCodec is used to map between int <-> Enum only. As your Enum is based on string, so please use EnumNameCodec class instead. Javadoc for these two codec classes are as per below. Hope it helps.

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 to Javadoc




回答2:


Change you code as follows:

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


来源:https://stackoverflow.com/questions/47996457/cassandra-codecnotfoundexception-codec-not-found-for-requested-operation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!