All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datastax.oss.driver.api.mapper.entity.EntityHelper Maven / Gradle / Ivy

There is a newer version: 4.15.0-yb-2-TESTFIX.0
Show newest version
/*
 * Copyright DataStax, Inc.
 *
 * Licensed 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.
 */
package com.datastax.oss.driver.api.mapper.entity;

import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.core.cql.BoundStatement;
import com.datastax.oss.driver.api.core.cql.BoundStatementBuilder;
import com.datastax.oss.driver.api.core.cql.Row;
import com.datastax.oss.driver.api.core.data.GettableByName;
import com.datastax.oss.driver.api.core.data.SettableByName;
import com.datastax.oss.driver.api.core.data.UdtValue;
import com.datastax.oss.driver.api.mapper.annotations.ClusteringColumn;
import com.datastax.oss.driver.api.mapper.annotations.CqlName;
import com.datastax.oss.driver.api.mapper.annotations.DaoKeyspace;
import com.datastax.oss.driver.api.mapper.annotations.DaoTable;
import com.datastax.oss.driver.api.mapper.annotations.Entity;
import com.datastax.oss.driver.api.mapper.annotations.NamingStrategy;
import com.datastax.oss.driver.api.mapper.annotations.PartitionKey;
import com.datastax.oss.driver.api.mapper.entity.saving.NullSavingStrategy;
import com.datastax.oss.driver.api.querybuilder.delete.Delete;
import com.datastax.oss.driver.api.querybuilder.insert.RegularInsert;
import com.datastax.oss.driver.api.querybuilder.select.Select;
import com.datastax.oss.driver.api.querybuilder.update.Update;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;

/**
 * A set of utility methods related to a particular mapped entity.
 *
 * 

The mapper processor generates an implementation of this interface for each {@link * Entity}-annotated class. It is used internally by other mapper components, and can also be * injected in custom query providers. */ public interface EntityHelper { /** * Sets the properties of an entity instance into a target data structure. * * @deprecated Use {@link #set(Object, SettableByName, NullSavingStrategy, boolean)} instead. */ @NonNull @Deprecated > SettableT set( @NonNull EntityT entity, @NonNull SettableT target, @NonNull NullSavingStrategy nullSavingStrategy); /** * Sets the properties of an entity instance into a target data structure. * *

The generated code will attempt to write all entity properties in the target data structure. * For example: * *

{@code
   * target = target.set("id", entity.getId(), UUID.class);
   * target = target.set("name", entity.getName(), String.class);
   * ...
   * }
* * The column names are inferred from the naming strategy for this entity. * *

The target will typically be one of the built-in driver subtypes: {@link BoundStatement}, * {@link BoundStatementBuilder} or {@link UdtValue}. Note that the default {@link BoundStatement} * implementation is immutable, therefore this argument won't be modified in-place: you need to * use the return value to get the resulting structure. * *

If {@code lenient} is {@code true}, the mapper will operate on a best-effort basis and * attempt to write all entity properties that have a matching column in the target, leaving * unmatched properties untouched. Beware that this may result in a partially-populated target. * *

If {@code lenient} is {@code false}, then the target must contain a matching column for * every property in the entity definition, except computed ones. If such a column is not * found, an {@link IllegalArgumentException} will be thrown. * * @param entity the entity that the values will be read from. * @param target the data structure to fill. * @param lenient whether to tolerate incomplete targets. * @return the data structure resulting from the assignments. This is useful for immutable target * implementations (see above), otherwise it will be the same as {@code target}. * @throws IllegalArgumentException if lenient is false and the target does not contain matching * columns for every entity property. */ @NonNull default > SettableT set( @NonNull EntityT entity, @NonNull SettableT target, @NonNull NullSavingStrategy nullSavingStrategy, boolean lenient) { return set(entity, target, nullSavingStrategy); } /** * Gets values from a data structure to fill an entity instance. * * @deprecated Use {@link #get(GettableByName, boolean)} instead. */ @NonNull @Deprecated EntityT get(@NonNull GettableByName source); /** * Gets values from a data structure to fill an entity instance. * *

The generated code will attempt to read all entity properties from the source data * structure. For example: * *

{@code
   * User returnValue = new User();
   * returnValue.setId(source.get("id", UUID.class));
   * returnValue.setName(source.get("name", String.class));
   * ...
   * }
* * The column names are inferred from the naming strategy for this entity. * *

The source will typically be one of the built-in driver subtypes: {@link Row} or {@link * UdtValue} ({@link BoundStatement} and {@link BoundStatementBuilder} are also possible, although * it's less likely that data would be read back from them in this manner). * *

If {@code lenient} is {@code true}, the mapper will operate on a best-effort basis and * attempt to read all entity properties that have a matching column in the source, leaving * unmatched properties untouched. Beware that this may result in a partially-populated entity * instance. * *

If {@code lenient} is {@code false}, then the source must contain a matching column for * every property in the entity definition, including computed ones. If such a column is * not found, an {@link IllegalArgumentException} will be thrown. * * @param source the data structure to read from. * @param lenient whether to tolerate incomplete sources. * @return the resulting entity. * @throws IllegalArgumentException if lenient is false and the source does not contain matching * columns for every entity property. */ @NonNull default EntityT get(@NonNull GettableByName source, boolean lenient) { return get(source); } /** * Builds an insert query for this entity. * *

The returned query is roughly the equivalent of: * *

{@code
   * QueryBuilder.insertInto(keyspaceId, tableId)
   *     .value("id", QueryBuilder.bindMarker("id"))
   *     .value("name", QueryBuilder.bindMarker("name"))
   *     ...
   * }
* * All mapped properties of the entity are included as bindable values (the bind markers have the * same names as the columns). * *

The column names are inferred from the naming strategy for this entity. * *

The keyspace and table identifiers are those of the DAO that this helper was obtained from; * if the DAO was built without a specific keyspace and table, the query doesn't specify a * keyspace, and the table name is inferred from the naming strategy. */ @NonNull RegularInsert insert(); /** * Builds the beginning of a Update query to update an entity. * *

This is the same as {@link #updateByPrimaryKey()} ()}, but without the {@code WHERE} clause. * This would typically not be executed as-is, but instead completed with a custom {@code WHERE} * clause (either added with the query builder DSL, or concatenated to the built query). */ @NonNull Update updateStart(); /** * Builds a Update query to update an instance of the entity by primary key (partition key + * clustering columns). * *

The returned query is roughly the equivalent of: * *

{@code
   * QueryBuilder.update(keyspaceId, tableId)
   *     .setColumn("description", QueryBuilder.bindMarker("description"))
   *     ... // (other non-PK columns)
   *     .where(Relation.column("id").isEqualTo(QueryBuilder.bindMarker("id"))
   *     ... // (other PK columns)
   * }
* * All non-PK properties of the entity are set, with bind markers that have the same names as the * columns. * *

All components of the primary key are listed in the {@code WHERE} clause as bindable values * (the bind markers have the same names as the columns). They are listed in the natural order, * i.e. partition key columns first, followed by clustering columns (in the order defined by the * {@link PartitionKey} and {@link ClusteringColumn} annotations on the entity class). * *

The keyspace and table identifiers are those of the DAO that this helper was obtained from; * if the DAO was built without a specific keyspace and table, the query doesn't specify a * keyspace, and the table name is inferred from the naming strategy. */ @NonNull Update updateByPrimaryKey(); /** * Builds a select query to fetch an instance of the entity by primary key (partition key + * clustering columns). * *

The returned query is roughly the equivalent of: * *

{@code
   * QueryBuilder.selectFrom(keyspaceId, tableId)
   *     .column("id")
   *     .column("name")
   *     .whereColumn("id").isEqualTo(QueryBuilder.bindMarker("id"));
   *   ...
   * }
* * All mapped properties of the entity are included in the result set. * *

All components of the primary key are listed in the {@code WHERE} clause as bindable values * (the bind markers have the same names as the columns). They are listed in the natural order, * i.e. partition key columns first, followed by clustering columns (in the order defined by the * {@link PartitionKey} and {@link ClusteringColumn} annotations on the entity class). * *

The keyspace and table identifiers are those of the DAO that this helper was obtained from; * if the DAO was built without a specific keyspace and table, the query doesn't specify a * keyspace, and the table name is inferred from the naming strategy. */ @NonNull Select selectByPrimaryKey(); /** * Builds the beginning of a select query to fetch one or more instances of the entity. * *

This is the same as {@link #selectByPrimaryKey()}, but without the {@code WHERE} clause. * This would typically not be executed as-is, but instead completed with a custom {@code WHERE} * clause (either added with the query builder DSL, or concatenated to the built query). */ @NonNull Select selectStart(); /** * Builds a delete query to delete an instance of the entity by primary key (partition key + * clustering columns). * *

The returned query is roughly the equivalent of: * *

{@code
   * Delete delete = QueryBuilder.deleteFrom(keyspaceId, tableId)
   *     .whereColumn("id").isEqualTo(QueryBuilder.bindMarker("id"));
   * }
* * All components of the primary key are listed in the {@code WHERE} clause as bindable values * (the bind markers have the same names as the columns). They are listed in the natural order, * i.e. partition key columns first, followed by clustering columns (in the order defined by the * {@link PartitionKey} and {@link ClusteringColumn} annotations on the entity class). * *

The keyspace and table identifiers are those of the DAO that this helper was obtained from; * * if the DAO was built without a specific keyspace and table, the query doesn't specify a * keyspace, and the table name is inferred from the naming strategy. */ @NonNull Delete deleteByPrimaryKey(); /** * The keyspace used in the queries generated by this helper. * *

This is determined by the following rules: * *

    *
  • If the DAO that this helper belongs to was created with a keyspace (see {@link * DaoKeyspace}), use that; *
  • Otherwise, if {@link Entity#defaultKeyspace()} is set for the entity class, use that; *
  • Otherwise, return {@code null}. *
*/ @Nullable CqlIdentifier getKeyspaceId(); /** * The table used in the queries generated by this helper. * *

This is determined by the following rules: * *

    *
  • If the DAO that this helper belongs to was created with a table (see {@link DaoTable}), * use that; *
  • Otherwise, if the entity class is annotated with {@link CqlName}, use that; *
  • Otherwise, use the name of the entity class, transformed by its {@link NamingStrategy}. *
*/ @NonNull CqlIdentifier getTableId(); /** The class of the mapped entity. */ @NonNull Class getEntityClass(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy