I’m building a DAO using Astyanax, Netflix’s Java client for Cassandra, and I’ve run into a couple issues.
Following their Getting Started guide, I was able to create my `keyspace` object through which I’ll be executing reads and writes. Retrieval by id (getKey()) and multiple ids (getKeySlice(Collection)) worked fine. I created a simple row mapper to create my objects from the `ColumnList` returned. So before getting into the errors, here are some instantiations:
# Cassandra table and keyspace constructed: CREATE TABLE users ( user_id text, username text, department int, PRIMARY KEY (user_id)); # Additional index for department CREATE INDEX department_key ON users (department);
private final ColumnFamily<String, String> USERS = new ColumnFamily<String, String>( "users", // Column Family Name StringSerializer.get(), // Key Serializer StringSerializer.get()); // Column Serializer
Bad Request: No indexed columns present in by-columns clause with Equal operator
My first error came from the execution of this CQL query:
OperationResult<CqlResult<String, String>> result = keyspace
.prepareQuery(USERS)
.withCql("SELECT * FROM users WHERE user_id = 'abc123'")
.execute();
// Also this fails:
OperationResult<CqlResult<String, String>> result = keyspace
.prepareQuery(USERS)
.withCql("SELECT * FROM users WHERE user_id = ?")
.asPreparedStatement()
.withStringValue(userId)
.execute();
Another problem I saw was the connection would simply timeout.
Solution
Set the CQL version (.setCqlVersion("3.0.0")) and Cassandra version (.setTargetCassandraVersion("2.0.7")) on my keyspace:
public void init() {
context = new AstyanaxContext.Builder()
.forKeyspace(keyspaceName)
.withAstyanaxConfiguration(
new AstyanaxConfigurationImpl()
.setTargetCassandraVersion("2.0.7")
.setCqlVersion("3.0.0")
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE))
.withConnectionPoolConfiguration(
new ConnectionPoolConfigurationImpl("MyConnectionPool").setPort(port)
.setMaxConnsPerHost(1).setSeeds(host + ":" + port))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getClient();
}
Not enough bytes to read value of component 0
Another problem is when trying to write to the table using a MutationBatch.
MutationBatch m = keyspace.prepareMutationBatch();
m.withRow(CF_USERS, u.getId())
.putColumn("user_id", u.getId())
.putColumn("username", u.getUsername())
.putColumn("department", u.getDepartment());
m.execute();
But it works with the preparedQuery:
String INSERT_STATEMENT = "INSERT INTO users (user_id, username, department) VALUES (?, ?, ?);";
keyspace.prepareQuery(CF_CONTENT_URL).withCql(INSERT_STATEMENT).asPreparedStatement()
.withIntegerValue(u.getId()).withStringValue(u.getUsername())
.withIntegerValue(u.getDepartment()).execute();
Solution
Create the table with COMPACT STORAGE. This unfortunately demands recreating your table, but then the MutationBatch runs fine. There is a warning in the documentation that you cannot update data in tables created with compact storage, but my tests do not confirm that.

That’s a skillful answer to a diilfcuft question