Hello Carlos and Oded,

Thanks to you all for your input!
@Carlos, I did not try the thrift client yet.
@Oded, thank you for deserializing the key. It looks exactly what to
expect, once it's deserialized...
I think we're onto something. I reproduced and simplified the case like
this. First I created a table like this:

CREATE TABLE mytesttable (
  tnt_id varint PRIMARY KEY,
  data text
) WITH COMPACT STORAGE;

I wrote two test clients.

*Hector*
First one uses Hector as a client, which we have used often in our
application.
Here some code:

public class HectorVarIntTest {

    final static String KEYSPACE = "sandbox";
    final static String CLUSTERNAME = "Test Cluster";
    final static String COLUMNFAMILY = "mytesttable";
    final static String HOST = "localhost:9160";

    static protected Keyspace getKeyspaceInstance() {
        return HFactory.createKeyspace(KEYSPACE,
HFactory.getOrCreateCluster(CLUSTERNAME, HOST));
    }

    public void insert(final Keyspace keyspace, final Integer partitionKey,
final String value) {
        final HColumn<String, String> column =
HFactory.createColumn("data", value);

        final Mutator<Integer> mutator = HFactory.createMutator(keyspace,
IntegerSerializer.get());
        mutator.addInsertion(partitionKey, COLUMNFAMILY, column);
        mutator.execute();
    }

    public static void main(final String[] args) {
        final Keyspace keyspace = getKeyspaceInstance();
        final HectorVarIntTest test = new HectorVarIntTest();
        test.insert(keyspace, 5, "hector test value");
    }

}

Note: when running this test against the same table *without* the COMPACT
STORAGE, the test would fail with an error like this:
InvalidRequestException(why:Not
enough bytes to read value of component 0)

*Java Driver 2.1 for Apache Cassandra*
The other client is using the Datastax Java driver (CQL), to which we are
migrating.
public class CqlVarIntTest {

    final static String KEYSPACE = "sandbox";
    final static String CLUSTERNAME = "Test Cluster";
    final static String TABLENAME = "mytesttable";
    final static String HOST = "localhost";

    public static void main(final String[] args) {
        final Cluster cluster =
Cluster.builder().addContactPoints(HOST).build();
        try {
            final Session session = cluster.connect(KEYSPACE);
            try {
                session.execute("INSERT INTO " + TABLENAME + "(tnt_id,
data) VALUES (5, 'cql test value')");
            } finally {
                session.close();
            }
        } finally {
            cluster.close();
        }
    }

}

I think this last test would have been the same as executing the query in
the CQL shell client, but I wanted to be sure how it was done by the Java
driver.

After running both tests this is what the table looks like:
cqlsh:sandbox> select * from mytesttable;

 tnt_id | data
--------+-------------------
      5 | hector test value
      5 |    cql test value

Interesting... Two records with the same *tnt_id*. That should not be
possible in this case?!

When converting the relevant sstable to json, we see this:
[
{"key": "05","columns": [["data","cql test value",1448361315125000]]},
{"key": "00000005","columns": [["data","hector test
value",1448361219355000]]}
]

So the keys are different after all. Hector is serializing varints
differently then the CQL Java Driver does.
But shouldn't the Cassandra host reject the Hector key in the first place?
Or should the Cassandra host re-serialize it so it's always stored in the
same way?

And does somebody know how to workaround this? How can I query these keys
inserted by Hector with the CQL (Java) client?

Thanks again!

Ramon

Reply via email to