2012-08-03 1 views
3

J'essaie d'insérer dans une famille de colonnes avec une clé composite en utilisant l'épargne en Java. Je reçois l'exception suivante:Insérer et obtenir de Cassandra avec Composite Légende: InvalidRequestException (pourquoi: Pas assez d'octets pour lire la valeur du composant 0)

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

Voici comment j'ai créé CF en utilisant CQLSH. Je veux insérer ("1", "2", "aaa") dans "test".

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

Voici mon code source, tout le monde a une idée de ce qui ne va pas ici et comment le faire fonctionner?

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); 

} 

Répondre

0

OK. Sortir sur un membre ici. Si vous voulez que la clé primaire soit composée de id1 et id2 dans cet ordre, lorsque vous insérez une ligne, vous ajoutez une seule colonne pour la valeur et la clé de la ligne et le nom de la colonne sont dérivés des valeurs id1 et id2.

La clé de ligne sera la valeur de id1.

Le nom de colonne pour la valeur sera une valeur composée constituée de la valeur de id1 ("1" dans ce cas) et du nom de la colonne id2 ("id2" dans ce cas).

Au moins c'est ce que vous auriez à faire dans Hector si vous n'utilisiez pas CQL directement.

+0

Merci pour votre réponse. J'ai essayé et je suis presque là. Sauf ne peut pas affecter de valeur à la colonne "valeur". J'ai posté mon nouveau code. Merci de votre aide. – Ashkan

+0

Avez-vous une erreur (runtime ou compilateur) et si oui, laquelle? –

0

OK. Enfin, j'ai compris comment insérer dans une ColumnFamily avec une clé composite en utilisant l'API thrift. Je dois dire que cela n'a aucun sens. Mais cela fonctionne:

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); 
Questions connexes