Issue
I have a requirement to fetch results from my cassandra database table in a paginated manner. I am using spring boot version 2.3.1 which in turn is using cassandra java driver 4. In previous driver versions, while paginating, there were no issues and the driver used to fetch the results equal to specified page size, like so:
Where select = QueryBuilder.select("column1", "column2", "column3")
.from("my_table")
.where(QueryBuilder.eq("column4", "some_value"))
.and(QueryBuilder.eq("column5", "some_value"));
select.setFetchSize(5);
if (!page.equals("0"))
select.setPagingState(PagingState.fromString(page));
ResultSet results = cassandraTemplate.getCqlOperations().queryForResultSet(select);
PagingState nextPage = results.getExecutionInfo().getPagingState();
int remaining = results.getAvailableWithoutFetching(); // gives 5 results as specified
In Java driver version 4, the method has been changed from setFetchSize(int) to setPageSize(int). But the same thing is not working here. It is fetching all the results even after specifying the size:
SimpleStatement stmt = QueryBuilder.selectFrom("my_keyspace", "my_table")
.columns(Arrays.asList("column1", "column2", "column3"))
.where(Relation.column("column4")
.isEqualTo(QueryBuilder.literal("some_value")),
Relation.column("column5")
.isEqualTo(QueryBuilder.literal("some_value))).build();
stmt.setPageSize(5);
if (!page.equals("0"))
stmt.setPagingState(Bytes.fromHexString(page));
ResultSet results = cassandraTemplate.getCqlOperations().queryForResultSet(stmt);
ByteBuffer nextPage = results.getExecutionInfo().getPagingState();
int remaining = results.getAvailableWithoutFetching(); // gives all the results, even though size is specified as 5
Am I doing something wrong? If I'm not then what should be the solution to this problem?
Solution
Statements in driver 4 are immutable. You need to change the following lines:
stmt = stmt.setPageSize(5);
if (!page.equals("0"))
stmt = stmt.setPagingState(Bytes.fromHexString(page));
IOW, each mutating method returns a new instance, so you need to capture that by reassigning the stmt
variable each time.
Answered By - adutra
Answer Checked By - Timothy Miller (JavaFixing Admin)