| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| --> |
| |
| ## Update methods |
| |
| Annotate a DAO method with [@Update] to generate a query that updates one or more |
| [entities](../../entities): |
| |
| ```java |
| @Dao |
| public interface ProductDao { |
| @Update |
| void update(Product product); |
| } |
| ``` |
| |
| ### Parameters |
| |
| The first parameter must be an entity instance. All of its non-PK properties will be interpreted as |
| values to update. |
| |
| * If the annotation doesn't have a `customWhereClause`, the mapper defaults to an update by primary |
| key (partition key + clustering columns). The WHERE clause is generated automatically, and bound |
| with the PK components of the provided entity instance. The query will update at most one row. |
| |
| * If the annotation has a `customWhereClause`, it completely replaces the WHERE clause. If the |
| provided string contains placeholders, the method must have corresponding additional parameters |
| (same name, and a compatible Java type): |
| |
| ```java |
| @Update(customWhereClause = "description LIKE :searchString") |
| void updateIfDescriptionMatches(Product product, String searchString); |
| ``` |
| |
| The PK components of the provided entity are ignored. Multiple rows may be updated. |
| |
| If the query has a custom timestamp or TTL with placeholders, the method must have corresponding |
| additional parameters (same name, and a compatible Java type): |
| |
| ```java |
| @Update(timestamp = ":timestamp") |
| void updateWithTimestamp(Product product, long timestamp); |
| |
| @Update(ttl = ":ttl") |
| void updateWithTtl(Product product, int ttl); |
| ``` |
| |
| An optional IF clause can be appended to the generated query. It can contain placeholders, for which |
| the method must have corresponding parameters (same name, and a compatible Java type): |
| |
| ```java |
| @Update(customIfClause = "description = :expectedDescription") |
| ResultSet updateIfDescriptionMatches(Product product, String expectedDescription); |
| ``` |
| |
| An optional IF EXISTS clause at the end of the generated UPDATE query. This is mutually exclusive |
| with `customIfClause` (if both are set, the mapper processor will generate a compile-time error): |
| |
| ```java |
| @Update(ifExists = true) |
| boolean updateIfExists(Product product); |
| ``` |
| |
| The annotation can define a [null saving strategy](../null_saving/) that applies to the properties |
| of the entity to update. This allows you to implement partial updates, by passing a "template" |
| entity that only contains the properties you want to modify: |
| |
| ```java |
| // DAO method definition: |
| @Update(customWhereClause = "id IN (:id1, :id2)", nullSavingStrategy = DO_NOT_SET) |
| void updateWhereIdIn(Product product, UUID id1, UUID id2); |
| |
| // Client code: |
| Product template = new Product(); |
| template.setDescription("Coming soon"); // all other properties remain null |
| dao.updateWhereIdIn(template, 42, 43); // Will only update 'description' on the selected rows |
| ``` |
| |
| A `Function<BoundStatementBuilder, BoundStatementBuilder>` or `UnaryOperator<BoundStatementBuilder>` |
| can be added as the **last** parameter. It will be applied to the statement before execution. This |
| allows you to customize certain aspects of the request (page size, timeout, etc) at runtime. See |
| [statement attributes](../statement_attributes/). |
| |
| ### Return type |
| |
| The method can return: |
| |
| * `void`. |
| |
| * a `boolean` or [Boolean], which will be mapped to `ResultSet#wasApplied()`. This is intended for |
| conditional queries. |
| |
| ```java |
| @Update(ifExists = true) |
| boolean updateIfExists(Product product); |
| ``` |
| |
| * a [ResultSet]. The method will return the raw query result, without any conversion. This is |
| intended for queries with custom IF clauses; when those queries are not applied, they return the |
| actual values of the tested columns. |
| |
| ```java |
| @Update(customIfClause = "description = :expectedDescription") |
| ResultSet updateIfExists(Product product); |
| // if the condition fails, the result set will contain columns '[applied]' and 'description' |
| ``` |
| |
| * a [BoundStatement]. This is intended for queries where you will execute this statement later or in a batch: |
| |
| ```java |
| @Update |
| BoundStatement update(Product product); |
| ``` |
| |
| * a [CompletionStage] or [CompletableFuture] of any of the above. The mapper will execute the query |
| asynchronously. |
| Note that for result sets, you need to switch to the asynchronous equivalent [AsyncResultSet]. |
| |
| ```java |
| @Update |
| CompletionStage<Void> update(Product product); |
| |
| @Update(ifExists = true) |
| CompletableFuture<Boolean> updateIfExists(Product product); |
| |
| @Update(customIfClause = "description = :expectedDescription") |
| CompletableFuture<AsyncResultSet> updateIfDescriptionMatches(Product product, String expectedDescription); |
| ``` |
| |
| * a [ReactiveResultSet]. |
| |
| ```java |
| @Update |
| ReactiveResultSet updateReactive(Product product); |
| ``` |
| |
| * a [custom type](../custom_types). |
| |
| ### Target keyspace and table |
| |
| If a keyspace was specified [when creating the DAO](../../mapper/#dao-factory-methods), then the |
| generated query targets that keyspace. Otherwise, it doesn't specify a keyspace, and will only work |
| if the mapper was built from a session that has a [default keyspace] set. |
| |
| If a table was specified when creating the DAO, then the generated query targets that table. |
| Otherwise, it uses the default table name for the entity (which is determined by the name of the |
| entity class and the naming convention). |
| |
| [default keyspace]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/session/SessionBuilder.html#withKeyspace-com.datastax.oss.driver.api.core.CqlIdentifier- |
| [@Update]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/mapper/annotations/Update.html |
| |
| [AsyncResultSet]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/cql/AsyncResultSet.html |
| [Boolean]: https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Boolean.html |
| [CompletionStage]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html |
| [CompletableFuture]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html |
| [ResultSet]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/cql/ResultSet.html |
| [BoundStatement]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/cql/BoundStatement.html |
| [ReactiveResultSet]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/cql/reactive/ReactiveResultSet.html |