question

wederbrand avatar image
wederbrand asked alexandre.dutra commented

How do I increment counters in Java driver 4.6.1?

java driver 4.6.1 seems incompatible with 3.7 when it comes to QueryBuilder.update() and incrementing counter columns

I'm using the java driver version 4.6.1 and a cassandra cluster running version 3.7

I'm trying to build a query using the builder, like this.

SimpleStatement incrementEnrollmentStageStatement = update("some_table")
.increment("a_counter_column")
.whereColumn("the_primary_key").isEqualTo(bindMarker())
.build();

The resulting CQL looks like this

UPDATE some_table SET a_counter_column+=1 WHERE the_primary_key=?

but trying to prepare this throwns an error, so does cqlsh if I try to run it.

line 1:39 no viable alternative at input '+'

In fact, "+=" increments aren't supported in 3.7, but are in 4.0.

Is this a bug? Am I doing anything wrong? This seems like the obvious way to do this.

I realize that append() works but looking at the javadocs for it says

Appends to a collection column, as in SET l=l+?.

As it works I'm fine but isn't this confusing? Perhaps the driver should identify older versions of cassandra and make increment work for those.

Thanks.

java drivercounter
1 comment
10 |1000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Erick Ramirez avatar image Erick Ramirez ♦♦ commented ·

Thanks for bringing this to our attention. I'll reach out to the Drivers team here at DataStax for a response. Cheers!

1 Like 1 ·
alexandre.dutra avatar image
alexandre.dutra answered alexandre.dutra commented

Indeed, QueryBuilder's increment() methods generate a += syntax that is only compatible with Cassandra 3.10+ (see CASSANDRA-12232).

We had a similar problem a while ago with append/prepend methods as well, see JAVA-2555. We fixed it by using "old style" assignments: col = col + ? instead of col += ?.

But it seems we should have done the same for increment/decrement methods.

Indeed I think as a workaround you could use append instead, it is meant primarily for collection appends, but in fact, there is not syntactical difference between a collection append and a counter increment.

This should get you unstuck, and in the meanwhile I will open a Jira ticket and we should have this fixed for the next 4.11.0 release.

3 comments Share
10 |1000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

alexandre.dutra avatar image alexandre.dutra ♦ commented ·

Hi, driver 4.11 has been released with the fix for JAVA-2928.

1 Like 1 ·
alexandre.dutra avatar image alexandre.dutra ♦ commented ·

The ticket is JAVA-2928.

0 Likes 0 ·
wederbrand avatar image wederbrand commented ·

Excellent. I switched over to .append yesterday and it works fine. I'm happy enough that there is a ticket to clarify things.


Cheers.

0 Likes 0 ·
cedrick.lunven_137390 avatar image
cedrick.lunven_137390 answered wederbrand commented

Hello @wederbrand and thank you for your questions.

4x brings a couple of syntax changes indeed. I created and try to maintain this project to help folks:https://github.com/DataStax-Examples/java-cassandra-driver-from3x-to4x

Specially for the counter you can look here: https://github.com/DataStax-Examples/java-cassandra-driver-from3x-to4x/blob/master/example-4x/src/main/java/com/datastax/samples/SampleCode4x_CRUD_08_Counters.java

Your syntax expect a value for the increment look at this:

PreparedStatement incStatement = session.prepare(QueryBuilder
       .update("videos")
       .increment("views", QueryBuilder.bindMarker())
       .whereColumn("videosid").isEqualTo(QueryBuilder.bindMarker())
       .build());

Cheers

1 comment Share
10 |1000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

wederbrand avatar image wederbrand commented ·

Yes, I know it works with 4.x.

My problem is that with the driver version 4.6.1 and cassandra version 3.7 using .increment() will NOT work, although the documentation suggests it.

.append() DOES work, but the documentation says it's for collections only.

0 Likes 0 ·