| <!-- |
| 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. |
| --> |
| |
| ## Delete methods |
| |
| Annotate a DAO method with [@Delete] to generate a query that deletes an [Entity](../../entities): |
| |
| ```java |
| @Dao |
| public interface ProductDao { |
| @Delete |
| void delete(Product product); |
| } |
| ``` |
| |
| ### Parameters |
| |
| The method can operate on: |
| |
| * an entity instance: |
| |
| ```java |
| @Delete |
| void delete(Product product); |
| ``` |
| |
| * a primary key (partition key + clustering columns): |
| |
| ```java |
| @Delete(entityClass = Product.class) |
| void deleteById(UUID productId); |
| ``` |
| |
| In this case, the parameters must match the types of the [primary key |
| columns](../../entities/#primary-key-columns), in the exact order (as defined by the |
| [@PartitionKey] and [@ClusteringColumn] annotations). The parameter names don't necessarily need |
| to match the names of the columns. |
| |
| In addition, because the entity class can't be inferred from the method signature, it must be |
| specified via the annotation's `entityClass` element. |
| |
| * a subset of the primary key. As in the partition key, or partition key + subset of clustering |
| columns: |
| |
| ```java |
| // given: PRIMARY KEY ((product_id, day), customer_id, ts) |
| // delete all rows in partition |
| @Delete(entityClass = ProductSale.class) |
| void deleteByIdForDay(UUID productId, LocalDate day); |
| |
| // delete by partition key and partial clustering key |
| @Delete(entityClass = ProductSale.class) |
| void deleteByIdForCustomer(UUID productId, LocalDate day, UUID customerId); |
| |
| /* Note that the clustering columns in your primary key definition are significant. All |
| * preceding clustering columns must be provided if any are. |
| * |
| * For example, the following is *NOT VALID* because ts is provided, but customer_id is |
| * not. */ |
| @Delete(entityClass = ProductSale.class) |
| void deleteByIdForTs(UUID productId, LocalDate day, long ts); |
| ``` |
| |
| * a number of parameters matching the placeholder markers in `customWhereClause`, for which |
| the parameters match the name and compatible java type of the markers: |
| |
| ```java |
| @Delete( |
| entityClass = ProductSale.class, |
| customWhereClause = |
| "id = :id and day = :day and customer_id = :customerId and ts >= :startTs and ts < :endTs") |
| ResultSet deleteInTimeRange(UUID id, String day, int customerId, UUID startTs, UUID endTs); |
| ``` |
| |
| An optional IF clause can be added to the generated query. Like `customWhereClause` it can contain |
| placeholders: |
| |
| ```java |
| @Delete(entityClass = Product.class, customIfClause = "description = :expectedDescription") |
| void deleteIfDescriptionMatches(UUID productId, String expectedDescription); |
| ``` |
| |
| 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 |
| IF EXISTS queries: |
| |
| ```java |
| /** @return true if the product did exist */ |
| @Delete(ifExists = true) |
| boolean deleteIfExists(Product product); |
| ``` |
| |
| * a [ResultSet]. 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 |
| @Delete(entityClass = Product.class, customIfClause = "description = :expectedDescription") |
| ResultSet deleteIfDescriptionMatches(UUID productId, String expectedDescription); |
| // 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 |
| @Delete |
| BoundStatement delete(Product product); |
| ``` |
| |
| * a [CompletionStage] or [CompletableFuture] of any of the above. The method will execute the query |
| asynchronously. Note that for result sets, you need to switch to [AsyncResultSet]. |
| |
| ```java |
| @Delete |
| CompletableFuture<Void> deleteAsync(Product product); |
| |
| @Delete(ifExists = true) |
| CompletionStage<Boolean> deleteIfExistsAsync(Product product); |
| |
| @Delete(entityClass = Product.class, customIfClause = "description = :expectedDescription") |
| CompletionStage<AsyncResultSet> deleteIfDescriptionMatchesAsync(UUID productId, String expectedDescription); |
| ``` |
| |
| * a [ReactiveResultSet]. |
| |
| ```java |
| @Delete |
| ReactiveResultSet deleteReactive(Product product); |
| ``` |
| |
| * a [custom type](../custom_types). |
| |
| Note that you can also return a boolean or result set for non-conditional queries, but there's no |
| practical purpose for that since those queries always return `wasApplied = true` and an empty result |
| set. |
| |
| ### 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 strategy](../../entities/#naming-strategy)). |
| |
| [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- |
| [AsyncResultSet]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/cql/AsyncResultSet.html |
| [@ClusteringColumn]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/mapper/annotations/ClusteringColumn.html |
| [@Delete]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/mapper/annotations/Delete.html |
| [@PartitionKey]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/mapper/annotations/PartitionKey.html |
| [ResultSet]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/cql/ResultSet.html |
| [ResultSet#wasApplied()]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/oss/driver/api/core/cql/ResultSet.html#wasApplied-- |
| [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 |
| |
| |
| [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 |