[ https://issues.apache.org/jira/browse/CASSANDRA-6426?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13836062#comment-13836062 ]
DOAN DuyHai commented on CASSANDRA-6426: ---------------------------------------- @Aleskey Thanks a lot for giving the rules! It's kind of not so obvious and not mentionned anywhere. I've just read the doc for batch statements for C* 2.0, it is said clearly that Timestamp can only be set on the batch statement and not on individual DML statements inside the batch: http://www.datastax.com/documentation/cql/3.1/webhelp/index.html#cql/cql_reference/batch_r.html#reference_ds_djf_xdd_xj {panel} *Individual DML statements inside a BATCH cannot specify a timestamp.* These individual statements can specify a TTL (time to live). TTL columns are automatically marked as deleted (with a tombstone) after the requested amount of time has expired. {panel} Is the doc accurate ? If yes, how can I guarantee the ORDER of my DML statements in a batch ? > Lost update in Prepared statement batch when a column is inserted with null > value in the same batch just before > --------------------------------------------------------------------------------------------------------------- > > Key: CASSANDRA-6426 > URL: https://issues.apache.org/jira/browse/CASSANDRA-6426 > Project: Cassandra > Issue Type: Bug > Components: Core > Environment: Cassandra Server 2.0.3 > Java Driver Core 2.0.0-rc1 > Reporter: DOAN DuyHai > > {panel:title=Test environment} > Cassandra Server *2.0.3* > Java Driver Core *2.0.0-rc1* > {panel} > While implementing batched prepared statements for Achilles, I ran into a > very annoying bug. > {code:title=FailingUnitTest.java|borderStyle=solid} > //Given > Long id = RandomUtils.nextLong(); > session.execute("CREATE TABLE test(id bigint, name text,label text, PRIMARY > KEY(id))"); > PreparedStatement insertPS = session.prepare("INSERT INTO test(id,name,label) > VALUES (?,?,?)"); > PreparedStatement updatePS = session.prepare("UPDATE test SET label=? WHERE > id=?"); > // Notice the "label" column is inserted first with null > BoundStatement insertBS = insertPS.bind(id, "myName", null); > // Then "label" is updated to "myLabel" > BoundStatement updateBS = updatePS.bind("myLabel", id); > //When > BatchStatement batch = new BatchStatement(); > batch.add(insertBS); > batch.add(updateBS); > session.execute(batch); > //Then > Statement statement = new SimpleStatement("SELECT * from test where id=" + > id); > Row row = session.execute(statement).one(); > // Assertion FAIL, "label" is NULL > assertThat(row.getString("label")).isEqualTo("myLabel"); > {code} > The above code always fails. > Even if I switch the order of the bound statements, e.g. *updateBS* added to > the batch before *insertBS*, the test still fails. > {code:title=WorkingUnitTest.java|borderStyle=solid} > //Given > Long id = RandomUtils.nextLong(); > session.execute("CREATE TABLE test(id bigint, name text,label text, PRIMARY > KEY(id))"); > PreparedStatement insertPS = session.prepare("INSERT INTO test(id,name) > VALUES (?,?)"); > PreparedStatement updatePS = session.prepare("UPDATE test SET label=? WHERE > id=?"); > // Notice the "label" column is removed from the insert statement > BoundStatement insertBS = insertPS.bind(id, "myName"); > BoundStatement updateBS = updatePS.bind("myLabel", id); > //When > BatchStatement batch = new BatchStatement(); > batch.add(updateBS); > batch.add(insertBS); > session.execute(batch); > //Then > Statement statement = new SimpleStatement("SELECT * from test where id=" + > id); > Row row = session.execute(statement).one(); > // Assertion SUCCEEDS here > assertThat(row.getString("label")).isEqualTo("myLabel"); > {code} > Only removing column "label" from the first insert bound statement can make > the test succeed. This is pretty annoying. > The rationale for inserting null values is that in Achilles I prepare > generic insert statements for all entities and setting NULL when the field is > not filled at runtime. > Currently, there is no guarantee for batch of prepared statement to be > executed in the order they are declared. -- This message was sent by Atlassian JIRA (v6.1#6144)