I'm getting started with Cassandra, and have been using the Hector Java library, which seems to be the most popular at the moment.
I'm trying to figure out how best to expose the data store to my Java code, and am trying to do something similar to the object-relational models I'm familiar with working with when using a relational data store.
Here is an example object which represents a user. Yes, its immutable, I'm going to handle mutation of these objects separately.
Note that I have created a separate class called Database which encapsulates the CassandraClientPool. The execWithKeyspace method takes a (Google Collections) Function and passes a Hector Keyspace to it. I'm doing it like this because it allows me to guarantee that the CassandraClient is returned to the pool once we're done with it.
Nonetheless, I'm really not sure whether I'm taking the best approach, and would appreciate some feedback:
public class User {
static final List<byte[]> colnames = Lists.newArrayList("Email".getBytes(), "Password-Hash".getBytes(),
"Name".getBytes(), "Company-Name".getBytes());
public static User getUser(final long id, final Database db) {
return db.execWithKeyspace(new Function<Keyspace, User>() {
@Override
public User apply(final Keyspace keyspace) {
final SlicePredicate sp = new SlicePredicate();
sp.setColumn_names(colnames);
final ColumnParent cp = new ColumnParent("Users");
final KeyRange kr = new KeyRange();
kr.setCount(1);
kr.setStart_key(Long.toString(id));
final Map<String, List<Column>> rangeSlices = keyspace.getRangeSlices(cp, sp, kr);
if (rangeSlices.size() != 1)
return null;
final List<Column> cols = rangeSlices.get(Long.toString(id));
if (cols == null)
return null;
return new User(id, string(cols.get(0).value), string(cols.get(1).value), string(cols.get(2).value),
string(cols.get(3).value));
}
});
}
final long id;
public final String email;
public final String passwordHash;
public final String name;
public final String companyName;
}