使用Composite Key从Cassandra插入和获取:InvalidRequestException(why:没有足够的字节来读取组件0的值)

时间:2012-08-03 18:28:44

标签: cassandra thrift composite-key

我正在尝试使用Java中的thrift插入带有复合键的列族。我得到以下异常:

 InvalidRequestException(why:Not enough bytes to read value of component 0)

这是我如何使用CQLSH创建CF.我想在“测试”中插入(“1”,“2”,“aaa”)。

CREATE COLUMNFAMILY test(id1 varchar,id2 varchar,value varchar,PRIMARY KEY(id1,id2));

这是我的源代码,任何人都知道这里有什么问题以及如何使它工作?

public static void main(String[] args) throws Exception {       

    TSocket socket = new TSocket("10.10.8.200", 9160);
    TFramedTransport transport = new TFramedTransport(socket);

    Cassandra.Client client = new Cassandra.Client(new TBinaryProtocol(transport));     
    transport.open();
    client.set_cql_version("3.0.0");
    client.set_keyspace("bigdata");

    ColumnParent parent = new ColumnParent("test");

    List<AbstractType<?>> keyTypes = new ArrayList<AbstractType<?>>(); 
    keyTypes.add(UTF8Type.instance);
    keyTypes.add(UTF8Type.instance);
    CompositeType compositeKey = CompositeType.getInstance(keyTypes);

    Builder builder = new Builder(compositeKey);
    builder.add(ByteBuffer.wrap("1".getBytes()));
    builder.add(ByteBuffer.wrap("2".getBytes()));
    ByteBuffer rowid = builder.build();

    Column column = new Column();
    column.setName("value".getBytes());
    column.setValue("aaa".getBytes());
    column.setTimestamp(System.currentTimeMillis());

    client.insert(rowid, parent, column, ConsistencyLevel.ONE);

}

2 个答案:

答案 0 :(得分:0)

行。在这里走出困境。如果您希望主键按顺序由id1和id2组成,那么当您插入一行时,您将为值添加一个列,并且行键和列名将从id1和id2的值派生。

行键将是id1的值。

值的列名称是一个复合值,由id1的值(本例中为“1”)和列id2的名称组成(本例中为“id2”)。

如果您没有直接使用CQL,至少这就是您在Hector中必须做的事情。

答案 1 :(得分:0)

行。最后,我想出了如何使用thrift API使用复合Key插入ColumnFamily。我不得不说,这没有任何意义。但它的确有效:

    ColumnParent parent = new ColumnParent("test");

    List<AbstractType<?>> keyTypes = new ArrayList<AbstractType<?>>(); 
    keyTypes.add(UTF8Type.instance);
    keyTypes.add(UTF8Type.instance);
    CompositeType compositeKey = CompositeType.getInstance(keyTypes);

    Builder builder = new Builder(compositeKey);
    builder.add(ByteBuffer.wrap("2".getBytes()));
    builder.add(ByteBuffer.wrap("value".getBytes()));
    ByteBuffer columnName = builder.build();


    Column column = new Column();
    column.setName(columnName);
    column.setValue("3".getBytes());
    column.setTimestamp(System.currentTimeMillis());

    client.insert(ByteBuffer.wrap("1".getBytes()), parent, column, ConsistencyLevel.ONE);