2
votes

Im currently working with Apache Cassandra (Cassandra version: 1.2.3, Thrift API version: 19.35.0, CQL supported versions: 2.0.0,3.0.1 (default: 3.0.1)) and Hector 1.0.5.

Im using the following code to insert and retrieve an Object.

String cf="User";
key="myKey";
String colName="colName";
String colValue="colvalue";

Mutator<String> mutator = HFactory.createMutator(keyspace, StringSerializer.get());
mutator.insert(key, cf, HFactory.createStringColumn(colName, colValue));



ColumnQuery<String, String, Object> columnQuery = HFactory.createColumnQuery(
    keyspace,
    StringSerializer.get(),
    StringSerializer.get(),
    ObjectSerializer.get());

    columnQuery.setColumnFamily(cf).setKey(key).setName(colName);
    QueryResult<HColumn<String, Object>> r = columnQuery.execute();

    System.out.println("Read HColumn from cassandra: " + r.get());

But I get the following exception:

Exception in thread "main" me.prettyprint.hector.api.exceptions.HectorSerializationException: java.io.StreamCorruptedException: invalid stream header: 636F6C76
    at me.prettyprint.cassandra.serializers.ObjectSerializer.fromByteBuffer(ObjectSerializer.java:79)
    at me.prettyprint.cassandra.model.HColumnImpl.getValue(HColumnImpl.java:124)
    at me.prettyprint.cassandra.model.HColumnImpl.toString(HColumnImpl.java:202)
    at java.lang.String.valueOf(String.java:2854)
    at java.lang.StringBuilder.append(StringBuilder.java:128)
    at org.dargamenteria.tfg.texu.logic.UserDAOImpl.create(UserDAOImpl.java:111)

But the following code works, just changed the ObjectSerializer to StringSerializer:

Mutator<String> mutator = HFactory.createMutator(keyspace, StringSerializer.get());
mutator.insert(key, cf, HFactory.createStringColumn(colName, colValue));

ColumnQuery<String, String, String> columnQuery = HFactory.createColumnQuery(
    keyspace,
    StringSerializer.get(),
    StringSerializer.get(),
    StringSerializer.get());

    columnQuery.setColumnFamily(cf).setKey(key).setName(colName);
    QueryResult<HColumn<String, String>> r = columnQuery.execute();

    System.out.println("Read HColumn from cassandra: " + r.get());
2

2 Answers

1
votes

If you look into Hector Serializer hierarchy, you will find that ObjectSerializer & StringSerializer are both siblings, both implementing Serializer interface and extending AbstractSerializer class.

fromByteBuffer method in StringSerializer is expecting a string, whereas in ObjectSerializer it is expecting an object. And in your code you have defined column value as string type, so you have to use StringSerializer as your set of code is expecting String type.

0
votes

First of all that thanks to Abhi, for its answer :) you gave some important clues.

What i did was inserting ByteBuffers by using the proper serializers. For example

mutator.addInsertion(key, columnFamilyName, 
HFactory.createColumn("name",                   
    ByteBufferSerializer.get().fromByteBuffer(StringSerializer.get().toByteBuffer(uh.getName())), 
    StringSerializer.get(),
    ByteBufferSerializer.get())).

addInsertion(key, columnFamilyName, 
HFactory.createColumn("email",                  
    ByteBufferSerializer.get().fromByteBuffer(ObjectSerializer.get().toByteBuffer(uh.getEmail())), 
    StringSerializer.get(),
    ByteBufferSerializer.get())).

And retrieving them for example

 StringSerializer.get().fromByteBuffer(
                r.get().getColumnByName("name").getValue())

Thank you all!