1

Having a problem with the 4.5 Datastax Cassandra driver. I cannot get any of these @Queries to work:

@Dao
public interface SampleTable2Dao extends BaseDao<SampleTable2> {
    //@Query("UPDATE sampletable2 SET cntrfld = cntrfld + :toAdd WHERE key1 = :key1Value AND key2 = :key2Value AND key3 = :key3Value")
    @Query("UPDATE sampletable2 SET cntrfld = cntrfld + 1 WHERE key1 = 1 AND key2 = 1 AND key3 = 1;")
    CompletableFuture<Void> addCountAsync(int toAdd, int key1Value, int key2Value, int key3Value);

    @Query("UPDATE sampletable2 SET cntrfld = cntrfld + 1 WHERE key1 = 1 AND key2 = 1 AND key3 = 1;")
    void addCount(int toAdd, int key1Value, int key2Value, int key3Value);

    @Query("UPDATE sampletable2 SET cntrfld = cntrfld + 1 WHERE key1 = 1 AND key2 = 1 AND key3 = 1;")
    void addCount();

It simply hangs: getSampleTable2Dao().addCount();

The queries work fine directly in Cassandra.

Thanks

P.S. here is the table for anyone wants to test:

CREATE TABLE sampletable2 (
    key1 int,
    key2 int,
    key3 int,
    cntrfld counter,
    PRIMARY KEY (key1, key2, key3)
);

update #1

After some digging, I find that it's in this generated code where it's hanging. Nothing to do with the actual query:

this.sampleTable2DaoCache = new LazyReference<>(() -> SampleTable2DaoImpl__MapperGenerated.init(context));

  @Override
  public SampleTable2Dao sampleTable2Dao() {
    return sampleTable2DaoCache.get();
  }

I'm working my way backwards stripping things out until I can get it working. Other DAOs work fine - the only difference with this is the counter field.

UPDATE #2... the "real" issue, is not @Query at all... but @Entity with counter fields.

@CqlName("cntrfld")
private Long cntrFld;

If this field is a counter in Cassandra (3.11.4 btw) the code just hangs. If I make the field a bigint, it works just fine!

Jason Nethercott
  • 373
  • 3
  • 20
  • It works for me. How are you building your session? One potential issue is that there is no keyspace in the query string, so your session needs to have a default one (`CqlSession.builder().withKeyspace(...)`). But still a missing keyspace should produce an error, not hang. – Olivier Michallat Apr 02 '20 at 16:40
  • That's not the issue... I cannot get it to connect without the keyspace... and it can connect. I have another dao working just fine. – Jason Nethercott Apr 02 '20 at 18:27
  • I tried 4.5.1, and it is still broken. I'm at a stand-still... Seems i cannot use a counter field with mappers. – Jason Nethercott Apr 02 '20 at 19:32

2 Answers2

2

I think you're trying to use @Insert or @Update with a counter column. That won't work: counters are a special type of column, they only support increment or decrement operations.

You can use an entity for read or delete operations though. But for updates, @Query is your only option right now:

@Entity @CqlName("sampletable2")
public class SampleTable2 {
  @PartitionKey private int key1;
  @ClusteringColumn(1) private int key2;
  @ClusteringColumn(2) private int key3;
  private long cntrfld;
  // getters and setters...
}

@Dao
public interface SampleTable2Dao {
  @Select
  SampleTable2 get(int key1, int key2, int key3);

  @Delete
  void delete(SampleTable2 entity);

  @Query(
      "UPDATE sampletable2 SET cntrfld = cntrfld + 1 "
          + "WHERE key1 = :key1 AND key2 = :key2 AND key3 = :key3")
  void increment(int key1, int key2, int key3);

  // THIS WON'T WORK:
  // @Insert
  // void insert(SampleTable2 entity);
}

Admittedly, we could have better support for counters in the mapper. I think something like this could work:

  @Increment
  void increment(SampleTable2 entity);

I've created JAVA-2721 to explore the idea.

Olivier Michallat
  • 2,302
  • 11
  • 13
  • Actually... my BaseDao does have an Insert... maybe that's it. I'll try to remove it. It should throw an error though, not just hang forever. just a thought. ;) – Jason Nethercott Apr 02 '20 at 22:28
  • I like the idea of an @ Increment. BUT, you need to be able to control the number to increment. I.E. @ Increment void increment(SampleTable2 entity, long delta); Or, would you have the code put the delta number in the entity variable field before calling? – Jason Nethercott Apr 03 '20 at 11:44
  • Yes, we'll have to refine the API a little bit: different increments (including negative), multiple counters, etc. – Olivier Michallat Apr 03 '20 at 17:09
1

The error was, my @Dao had an @Insert, but the table used a counter field type. Once I removed the @Insert, then the system worked.

I followed the help and created a BaseDao< T > class that contained repetitive @Insert and @Delete sets of methods, so it wasn't obvious what I had wrong.

The library SHOULD throw an error in this situation, and not just hang... that's a bug int he library I think.

Jason Nethercott
  • 373
  • 3
  • 20
  • I am getting an error by the way: `com.datastax.oss.driver.api.core.servererrors.InvalidQueryException: INSERT statements are not allowed on counter tables, use UPDATE instead` when I get the DAO from the mapper. There might be something else going on, try debugging maybe. – Olivier Michallat Apr 03 '20 at 17:24