Frequently Asked Questions

How do I implement paging?

When using native protocol version 2 or higher, the driver automatically pages large result sets under the hood. You can also save the paging state to resume iteration later. See this page for more information.

Native protocol v1 does not support paging, but you can emulate it in CQL with LIMIT and the token() function. See this conversation on the mailing list.

Can I check if a conditional statement (lightweight transaction) was successful?

When executing a conditional statement, the ResultSet will contain a single Row with a column named “applied” of type boolean. This tells whether the conditional statement was successful or not.

The driver provides a convenience method wasApplied to check this on the result set directly:

ResultSet rset = session.execute(conditionalStatement);
rset.wasApplied();

You may also inspect the value yourself:

ResultSet rset = session.execute(conditionalStatement);
Row row = rset.one();
row.getBool(0);       // this is equivalent row.getBool("applied")

Note that, unlike manual inspection, wasApplied does not consume the first row.

What is a parameterized statement and how can I use it?

Starting with Cassandra 2.0, normal statements (that is non-prepared statements) do not need to concatenate parameter values inside a query string. Instead you can use ? markers and provide the values separately:

session.execute( "INSERT INTO contacts (email, firstname, lastname)
      VALUES (?, ?, ?)", "clint.barton@hawkeye.com", "Barney", "Barton");

See Simple statements for more information.

Does a parameterized statement escape parameters?

A parameterized statement sends the values of parameters separate from the query (similar to the way a prepared statement does) as bytes so there is no need to escape parameters.

What’s the difference between a parameterized statement and a Prepared statement?

The only similarity between a parameterized statement and a prepared statement is in the way that the parameters are sent. The difference is that a prepared statement:

  • is already known on the cluster side (it has been compiled and there is an execution plan available for it) which leads to better performance
  • sends only the statement id and its parameters (thus reducing the amount of data sent to the cluster)

See Prepared statements for more information.

Can I combine PreparedStatements and normal statements in a batch?

Yes. A batch can include both bound statements and simple statements:

PreparedStatement ps = session.prepare( "INSERT INTO contacts (email, firstname, lastname)
      VALUES (?, ?, ?)");
BatchStatement batch = new BatchStatement();
batch.add(ps.bind(...));
batch.add(ps.bind(...));
// here's a simple statement 
batch.add(new SimpleStatement( "INSERT INTO contacts (email, firstname, lastname) VALUES (?, ?, ?)", ...));
session.execute(batch);

Can I get the raw bytes of a text column?

If you need to access the raw bytes of a text column, call the Row.getBytesUnsafe("columnName") method.

Trying to use Row.getBytes("columnName") for the same purpose results in an exception, as the getBytes method can only be used if the column has the CQL type BLOB.

How do I increment counters with QueryBuilder?

Considering the following query:

UPDATE clickstream SET clicks = clicks + 1 WHERE userid = id;

To do this using QueryBuilder:

Statement query = QueryBuilder.update("clickstream")
                              .with(incr("clicks", 1)) // Use incr for counters
                              .where(eq("userid", id));

Is there a way to control the batch size of the results returned from a query?

Use the setFetchSize() method on your Statement object. The fetch size controls how many resulting rows are retrieved simultaneously (the goal being to avoid loading too many results in memory for queries yielding large result sets).

Keep in mind that if your code iterates the ResultSet entirely, the driver may run additional background queries to fetch the rest of the data. The fetch size only affects what is retrieved at a time, not the overall number of rows.

See Paging for more information.

What’s the difference between using setFetchSize() and LIMIT?

Basically, LIMIT controls the maximum number of results returned by the query, while the setFetchSize() method controls the amount of data transferred at a time.

For example, if you limit is 30 and your fetch size is 10, the ResultSet will contain 30 rows, but under the hood the driver will perform 3 requests that will transfer 10 rows each.

See Paging for more information.