diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AbstractCreateQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AbstractCreateQuery.java index 7c5d3a0cb..1bbc8c60e 100644 --- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AbstractCreateQuery.java +++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AbstractCreateQuery.java @@ -17,19 +17,30 @@ import org.seasar.doma.jdbc.Sql; +/** + * An abstract base class for queries that create database resources. + * + *
This class provides a skeletal implementation of the {@link CreateQuery} interface, reducing
+ * the effort required to implement resource creation queries.
+ *
+ * @param This class provides common functionality for all query types.
+ */
public abstract class AbstractQuery implements Query {
+ /** The class name of the caller. */
protected String callerClassName;
+ /** The method name of the caller. */
protected String callerMethodName;
+ /** The configuration. */
protected Config config;
+ /** The method that defines the query. */
protected Method method;
+ /** The query timeout in seconds. */
protected int queryTimeout;
+ /** The message to be included in SQL comments. */
protected String message;
+ /** The context for SQL comments. */
private CommentContext commentContext;
+ /** Creates a new instance. */
protected AbstractQuery() {}
+ /** {@inheritDoc} */
@Override
public String getClassName() {
return callerClassName;
}
+ /**
+ * Sets the class name of the caller.
+ *
+ * @param callerClassName the class name
+ */
public void setCallerClassName(String callerClassName) {
this.callerClassName = callerClassName;
}
+ /** {@inheritDoc} */
@Override
public String getMethodName() {
return callerMethodName;
}
+ /**
+ * Sets the method name of the caller.
+ *
+ * @param callerMethodName the method name
+ */
public void setCallerMethodName(String callerMethodName) {
this.callerMethodName = callerMethodName;
}
+ /** {@inheritDoc} */
@Override
public Config getConfig() {
return config;
}
+ /**
+ * Sets the configuration.
+ *
+ * @param config the configuration
+ */
public void setConfig(Config config) {
this.config = config;
}
+ /** {@inheritDoc} */
@Override
public Method getMethod() {
return method;
}
+ /**
+ * Sets the method that defines the query.
+ *
+ * @param method the method
+ */
public void setMethod(Method method) {
this.method = method;
}
+ /** {@inheritDoc} */
@Override
public int getQueryTimeout() {
return queryTimeout;
}
+ /**
+ * Sets the query timeout in seconds.
+ *
+ * @param queryTimeout the query timeout
+ */
public void setQueryTimeout(int queryTimeout) {
this.queryTimeout = queryTimeout;
}
+ /**
+ * Sets the message to be included in SQL comments.
+ *
+ * @param message the message
+ */
public void setMessage(String message) {
this.message = message;
}
+ /** {@inheritDoc} */
@Override
public void prepare() {
assertNotNull(callerClassName, callerMethodName, config);
commentContext = new CommentContext(callerClassName, callerMethodName, config, method, message);
}
+ /** {@inheritDoc} */
@Override
public String comment(String sql) {
assertNotNull(sql, config, commentContext);
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AbstractSelectQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AbstractSelectQuery.java
index 6556ffa39..d7687ad05 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AbstractSelectQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AbstractSelectQuery.java
@@ -51,34 +51,57 @@
import org.seasar.doma.message.Message;
import org.seasar.doma.wrapper.PrimitiveLongWrapper;
+/**
+ * The base abstract class for all select query implementations.
+ *
+ * This class provides common functionality for queries that select data from a database.
+ */
public abstract class AbstractSelectQuery extends AbstractQuery implements SelectQuery {
+ /** The parameters for the query. */
protected final Map This implementation prepares options and SQL.
+ */
@Override
public void prepare() {
super.prepare();
@@ -87,6 +110,12 @@ public void prepare() {
assertNotNull(sql);
}
+ /**
+ * Prepares the options for this query.
+ *
+ * This method sets default values for fetch size, max rows, and query timeout if they are not
+ * already set.
+ */
protected void prepareOptions() {
if (fetchSize <= 0) {
fetchSize = config.getFetchSize();
@@ -99,8 +128,19 @@ protected void prepareOptions() {
}
}
+ /**
+ * Prepares the SQL for this query.
+ *
+ * This method must be implemented by subclasses to build the SQL statement.
+ */
protected abstract void prepareSql();
+ /**
+ * Builds the SQL for this query using the provided SQL builder.
+ *
+ * @param sqlBuilder the function to build the SQL
+ * @deprecated This method is scheduled for removal in a future version
+ */
@Deprecated(forRemoval = true)
protected void buildSql(
BiFunction This class extends {@link AbstractCreateQuery} to provide functionality for creating SQL
+ * arrays in a database. It handles the creation of JDBC {@link Array} objects by specifying the SQL
+ * type name and array elements.
+ */
public class ArrayCreateQuery extends AbstractCreateQuery This class implements {@link BatchDeleteQuery} to provide batch DELETE operations for
+ * entities. It handles version checking for optimistic locking and supports tenant ID-based
+ * isolation.
+ *
+ * @param This method validates the state of this instance, prepares SQL statements for all entities,
+ * and ensures that the number of SQL statements matches the number of entities.
+ */
@Override
public void prepare() {
super.prepare();
@@ -70,6 +92,12 @@ public void prepare() {
assertEquals(size, sqls.size());
}
+ /**
+ * Executes pre-delete processing for the current entity.
+ *
+ * This method creates a context for pre-delete operations and calls the entity type's
+ * preDelete method. If a new entity is returned by the context, it replaces the current entity.
+ */
protected void preDelete() {
AutoBatchPreDeleteContext This method sets the optimistic lock check flag based on the version property type and the
+ * configuration settings for version handling and exception suppression.
+ */
protected void prepareOptimisticLock() {
if (versionPropertyType != null && !versionIgnored) {
if (!optimisticLockExceptionSuppressed) {
@@ -87,6 +121,13 @@ protected void prepareOptimisticLock() {
}
}
+ /**
+ * Prepares the SQL statement for the current entity.
+ *
+ * This method builds a DELETE SQL statement with appropriate WHERE clauses for ID properties,
+ * version property (for optimistic locking), and tenant ID property (for multi-tenancy). The
+ * completed SQL statement is added to the list of SQL statements to be executed.
+ */
protected void prepareSql() {
Naming naming = config.getNaming();
Dialect dialect = config.getDialect();
@@ -139,6 +180,12 @@ protected void prepareSql() {
sqls.add(sql);
}
+ /**
+ * Completes this query after execution.
+ *
+ * This method performs post-processing for all entities after the batch delete operation has
+ * been executed. It calls the postDelete method for each entity.
+ */
@Override
public void complete() {
for (ListIterator This method creates a context for post-delete operations and calls the entity type's
+ * postDelete method. If a new entity is returned by the context, it replaces the current entity.
+ */
protected void postDelete() {
AutoBatchPostDeleteContext This class implements {@link BatchInsertQuery} to provide batch INSERT operations for
+ * entities. It handles ID generation, version initialization, and supports various duplicate key
+ * handling strategies.
+ *
+ * @param This method processes all entities in the batch, applying pre-insert hooks, preparing ID and
+ * version values, and generating SQL statements for each entity.
+ */
@Override
public void prepare() {
super.prepare();
@@ -106,6 +147,12 @@ public void prepare() {
assertEquals(entities.size(), sqls.size());
}
+ /**
+ * Executes pre-insert hooks on the current entity.
+ *
+ * This method creates a context for pre-insert processing and applies entity-specific
+ * pre-insert logic to the current entity.
+ */
protected void preInsert() {
AutoBatchPreInsertContext This method initializes the generated ID property type and configures ID generation
+ * settings, including whether batch operations and auto-generated keys are supported.
+ */
@Override
protected void prepareIdAndVersionPropertyTypes() {
super.prepareIdAndVersionPropertyTypes();
@@ -132,6 +185,13 @@ protected void prepareIdAndVersionPropertyTypes() {
}
}
+ /**
+ * Prepares the target property types for this query.
+ *
+ * This method determines which entity properties should be included in the INSERT statement
+ * based on their insertability, ID status, and other criteria. It also validates that
+ * non-generated ID properties have non-null values.
+ */
protected void prepareTargetPropertyTypes() {
targetPropertyTypes = new ArrayList<>(entityType.getEntityPropertyTypes().size());
for (EntityPropertyType If a generated ID property type is configured, this method applies pre-insert ID generation
+ * logic to the current entity.
+ */
protected void prepareIdValue() {
if (generatedIdPropertyType != null && idGenerationConfig != null) {
currentEntity =
@@ -167,12 +233,24 @@ protected void prepareIdValue() {
}
}
+ /**
+ * Prepares the version value for the current entity.
+ *
+ * If a version property type is configured, this method initializes the version value to 1 for
+ * the current entity.
+ */
protected void prepareVersionValue() {
if (versionPropertyType != null) {
currentEntity = versionPropertyType.setIfNecessary(entityType, currentEntity, 1);
}
}
+ /**
+ * Prepares the SQL statement for the current entity.
+ *
+ * This method builds the appropriate SQL statement (INSERT or UPSERT) based on the duplicate
+ * key handling strategy and dialect capabilities.
+ */
protected void prepareSql() {
Naming naming = config.getNaming();
Dialect dialect = config.getDialect();
@@ -235,11 +313,25 @@ private void assembleUpsertSql(PreparedSqlBuilder builder, Naming naming, Dialec
upsertAssembler.assemble();
}
+ /**
+ * Determines whether batch operations are supported for this query.
+ *
+ * @return true if batch operations are supported, false otherwise
+ */
@Override
public boolean isBatchSupported() {
return batchSupported;
}
+ /**
+ * Generates an ID for the entity at the specified index using auto-generated keys.
+ *
+ * This method retrieves the auto-generated key from the statement and updates the entity with
+ * the generated ID value.
+ *
+ * @param statement the statement that executed the insert
+ * @param index the index of the entity in the batch
+ */
@Override
public void generateId(Statement statement, int index) {
if (isAutoGeneratedKeysSupported()) {
@@ -255,6 +347,17 @@ public void generateId(Statement statement, int index) {
}
}
+ /**
+ * Generates IDs for a range of entities using auto-generated keys.
+ *
+ * This method retrieves auto-generated keys from the statement and updates the specified range
+ * of entities with the generated ID values.
+ *
+ * @param statement the statement that executed the batch insert
+ * @param position the starting position in the entities list
+ * @param size the number of entities to process
+ * @throws DomaIllegalArgumentException if the position and size parameters are invalid
+ */
@Override
public void generateIds(Statement statement, int position, int size) {
if (isAutoGeneratedKeysSupported() && isBatchSupported()) {
@@ -281,6 +384,12 @@ public void generateIds(Statement statement, int position, int size) {
}
}
+ /**
+ * Completes the batch insert operation.
+ *
+ * This method applies post-insert hooks to all entities in the batch after the database
+ * operation has been executed.
+ */
@Override
public void complete() {
for (ListIterator This method creates a context for post-insert processing and applies entity-specific
+ * post-insert logic to the current entity.
+ */
protected void postInsert() {
AutoBatchPostInsertContext This context is used during the pre-insert phase of batch insert operations to provide
+ * entity-specific processing.
+ *
+ * @param This context is used during the post-insert phase of batch insert operations to provide
+ * entity-specific processing after database operations have been executed.
+ *
+ * @param This class provides common functionality for batch operations that modify entities in the
+ * database, such as batch insert, update, and delete operations. It manages entity properties,
+ * optimistic locking, and SQL generation for batch operations.
+ *
+ * @param This method initializes the property types that are used for identifying entities and
+ * handling optimistic locking and multi-tenancy.
+ */
protected void prepareIdAndVersionPropertyTypes() {
idPropertyTypes = entityType.getIdPropertyTypes();
versionPropertyType = entityType.getVersionPropertyType();
tenantIdPropertyType = entityType.getTenantIdPropertyType();
}
+ /**
+ * Validates that the entity has at least one ID property.
+ *
+ * This method throws a {@link JdbcException} if the entity doesn't have any ID properties, as
+ * batch operations require entities to be identifiable.
+ *
+ * @throws JdbcException if the entity doesn't have any ID properties
+ */
protected void validateIdExistent() {
if (idPropertyTypes.isEmpty()) {
throw new JdbcException(Message.DOMA2022, entityType.getName());
}
}
+ /**
+ * Prepares the query options.
+ *
+ * This method initializes the query timeout and batch size from the configuration if they
+ * haven't been explicitly set or if they have invalid values.
+ */
protected void prepareOptions() {
if (queryTimeout <= 0) {
queryTimeout = config.getQueryTimeout();
@@ -94,6 +140,16 @@ protected void prepareOptions() {
}
}
+ /**
+ * Determines if a property should be included in the query based on its name.
+ *
+ * This method checks if the property name is in the included properties list and not in the
+ * excluded properties list. If no included properties are specified, all properties except those
+ * explicitly excluded are considered targets.
+ *
+ * @param name the property name to check
+ * @return {@code true} if the property should be included, {@code false} otherwise
+ */
protected boolean isTargetPropertyName(String name) {
if (includedPropertyNames.length > 0) {
for (String includedName : includedPropertyNames) {
@@ -119,6 +175,15 @@ protected boolean isTargetPropertyName(String name) {
return true;
}
+ /**
+ * Sets the entities to be processed by this batch query.
+ *
+ * This method initializes the internal list of entities and prepares the SQL statements list
+ * with the same size as the entities list.
+ *
+ * @param entities the entities to be processed
+ * @throws NullPointerException if {@code entities} is {@code null}
+ */
public void setEntities(Iterable The batch size determines how many entities are processed in a single batch operation.
+ *
+ * @param batchSize the batch size
+ */
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
+ /**
+ * Sets the names of properties to be included in the query.
+ *
+ * If this is set, only the specified properties will be included in the query, unless they are
+ * also in the excluded properties list.
+ *
+ * @param includedPropertyNames the names of properties to include
+ */
public void setIncludedPropertyNames(String... includedPropertyNames) {
this.includedPropertyNames = includedPropertyNames;
}
+ /**
+ * Sets the names of properties to be excluded from the query.
+ *
+ * If this is set, the specified properties will be excluded from the query, even if they are
+ * in the included properties list.
+ *
+ * @param excludedPropertyNames the names of properties to exclude
+ */
public void setExcludedPropertyNames(String... excludedPropertyNames) {
this.excludedPropertyNames = excludedPropertyNames;
}
+ /**
+ * Sets the SQL log type for this query.
+ *
+ * The SQL log type determines how SQL statements are logged.
+ *
+ * @param sqlLogType the SQL log type
+ */
public void setSqlLogType(SqlLogType sqlLogType) {
this.sqlLogType = sqlLogType;
}
+ /**
+ * Returns the first SQL statement in the batch.
+ *
+ * @return the first SQL statement
+ */
@Override
public PreparedSql getSql() {
return sqls.get(0);
}
+ /**
+ * Returns all SQL statements in the batch.
+ *
+ * @return the list of SQL statements
+ */
@Override
public List This class implements {@link BatchUpdateQuery} to provide batch UPDATE operations for
+ * entities. It handles version checking for optimistic locking and supports tenant ID-based
+ * isolation.
+ *
+ * @param This method initializes the query by setting up the helper, preparing the entities, and
+ * generating SQL statements for each entity in the batch.
+ */
@Override
public void prepare() {
super.prepare();
@@ -72,6 +90,12 @@ public void prepare() {
assertEquals(entities.size(), sqls.size());
}
+ /**
+ * Sets up the batch update query helper.
+ *
+ * This method initializes the helper with the configuration, entity type, included and
+ * excluded property names, and optimistic locking settings.
+ */
protected void setupHelper() {
helper =
new BatchUpdateQueryHelper<>(
@@ -83,6 +107,12 @@ protected void setupHelper() {
optimisticLockExceptionSuppressed);
}
+ /**
+ * Executes pre-update processing for the current entity.
+ *
+ * This method calls the entity type's preUpdate method with the current entity and updates the
+ * current entity if a new entity is returned from the context.
+ */
protected void preUpdate() {
AutoBatchPreUpdateContext This method sets the optimistic lock check flag based on the version property type and the
+ * version ignored and optimistic lock exception suppressed flags.
+ */
protected void prepareOptimisticLock() {
if (versionPropertyType != null && !versionIgnored) {
if (!optimisticLockExceptionSuppressed) {
@@ -100,6 +136,12 @@ protected void prepareOptimisticLock() {
}
}
+ /**
+ * Prepares the target property types for this query.
+ *
+ * This method gets the target property types from the helper and sets the executable flag to
+ * true if there are any target properties to update.
+ */
protected void prepareTargetPropertyTypes() {
targetPropertyTypes = helper.getTargetPropertyTypes();
if (!targetPropertyTypes.isEmpty()) {
@@ -108,6 +150,13 @@ protected void prepareTargetPropertyTypes() {
}
}
+ /**
+ * Prepares the SQL statement for the current entity.
+ *
+ * This method builds an UPDATE SQL statement with the appropriate SET clause for the target
+ * properties and WHERE clause for the ID properties, version property, and tenant ID property as
+ * needed.
+ */
protected void prepareSql() {
Naming naming = config.getNaming();
Dialect dialect = config.getDialect();
@@ -162,6 +211,12 @@ protected void prepareSql() {
sqls.add(sql);
}
+ /**
+ * Increments the version property values of all entities.
+ *
+ * This method is called after successful execution of the batch update to increment the
+ * version values for optimistic locking.
+ */
@Override
public void incrementVersions() {
if (versionPropertyType != null && !versionIgnored) {
@@ -172,6 +227,12 @@ public void incrementVersions() {
}
}
+ /**
+ * Completes this query by performing post-update processing for all entities.
+ *
+ * This method is called after the batch update has been executed to perform any necessary
+ * post-processing on the entities.
+ */
@Override
public void complete() {
for (ListIterator This method calls the entity type's postUpdate method with the current entity, updates the
+ * current entity if a new entity is returned from the context, and saves the current states of
+ * the entity.
+ */
protected void postUpdate() {
AutoBatchPostUpdateContext If set to {@code true}, the version property will not be used for optimistic locking in the
+ * WHERE clause of the UPDATE statement, and the version will not be incremented.
+ *
+ * @param versionIgnored whether to ignore the version property
+ */
public void setVersionIgnored(boolean versionIgnored) {
this.versionIgnored |= versionIgnored;
}
+ /**
+ * Sets whether to suppress optimistic lock exceptions.
+ *
+ * If set to {@code true}, optimistic lock exceptions will not be thrown even if the version
+ * check fails during the update operation.
+ *
+ * @param optimisticLockExceptionSuppressed whether to suppress optimistic lock exceptions
+ */
public void setOptimisticLockExceptionSuppressed(boolean optimisticLockExceptionSuppressed) {
this.optimisticLockExceptionSuppressed = optimisticLockExceptionSuppressed;
}
+ /**
+ * A context class for pre-update processing in batch update operations.
+ *
+ * This class provides context information for the pre-update phase of batch update operations.
+ *
+ * @param This method always returns {@code true} for batch update operations.
+ *
+ * @return {@code true}
+ */
@Override
public boolean isEntityChanged() {
return true;
}
+ /**
+ * Indicates whether the specified property has been changed.
+ *
+ * This method always returns {@code true} for batch update operations.
+ *
+ * @param propertyName the property name
+ * @return {@code true}
+ * @throws IllegalArgumentException if the property is not defined in the entity
+ */
@Override
public boolean isPropertyChanged(String propertyName) {
validatePropertyDefined(propertyName);
@@ -217,12 +331,36 @@ public boolean isPropertyChanged(String propertyName) {
}
}
+ /**
+ * A context class for post-update processing in batch update operations.
+ *
+ * This class provides context information for the post-update phase of batch update
+ * operations.
+ *
+ * @param This method always returns {@code true} for batch update operations.
+ *
+ * @param propertyName the property name
+ * @return {@code true}
+ * @throws IllegalArgumentException if the property is not defined in the entity
+ */
@Override
public boolean isPropertyChanged(String propertyName) {
validatePropertyDefined(propertyName);
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoDeleteQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoDeleteQuery.java
index 4494360d4..6b3d43b8d 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoDeleteQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoDeleteQuery.java
@@ -27,16 +27,38 @@
import org.seasar.doma.jdbc.dialect.Dialect;
import org.seasar.doma.jdbc.entity.EntityType;
+/**
+ * An auto delete query that is executed against an entity class.
+ *
+ * This class implements {@link DeleteQuery} to provide DELETE operations for entities. It
+ * handles version checking for optimistic locking and supports tenant ID-based isolation.
+ *
+ * @param This implementation prepares the query for execution by performing pre-delete operations,
+ * preparing special property types, validating ID existence, preparing options and optimistic
+ * locking, and building the SQL statement.
+ */
@Override
public void prepare() {
super.prepare();
@@ -51,6 +73,10 @@ public void prepare() {
assertNotNull(sql);
}
+ /**
+ * Performs pre-delete operations on the entity. This method is called before the entity is
+ * deleted from the database.
+ */
protected void preDelete() {
AutoPreDeleteContext This implementation performs post-delete operations on the entity.
+ */
@Override
public void complete() {
postDelete();
}
+ /**
+ * Performs post-delete operations on the entity. This method is called after the entity is
+ * deleted from the database.
+ */
protected void postDelete() {
AutoPostDeleteContext This class implements {@link FunctionQuery} to provide functionality for calling database
+ * functions. It handles parameter binding and result retrieval.
+ *
+ * @param This method builds the callable SQL statement for the function call.
+ */
protected void prepareSql() {
CallableSqlBuilder builder =
new CallableSqlBuilder(
@@ -42,14 +57,25 @@ protected void prepareSql() {
sql = builder.build(this::comment);
}
+ /**
+ * Sets the function name.
+ *
+ * @param functionName the function name
+ */
public void setFunctionName(String functionName) {
setModuleName(functionName);
}
+ /**
+ * Sets the result parameter.
+ *
+ * @param parameter the result parameter
+ */
public void setResultParameter(ResultParameter This class provides functionality to generate and execute SQL INSERT statements based on
+ * entity definitions. It handles various insert scenarios including:
+ *
+ * The query execution process includes:
+ *
+ * This method performs the following operations:
+ *
+ * This method creates a pre-insert context and calls the entity's preInsert method, allowing
+ * entity listeners to modify the entity before insertion.
+ */
protected void preInsert() {
AutoPreInsertContext This method initializes the generated ID property type and its configuration, and determines
+ * if auto-generated keys are supported for this query.
+ */
@Override
protected void prepareSpecialPropertyTypes() {
super.prepareSpecialPropertyTypes();
@@ -92,6 +161,22 @@ protected void prepareSpecialPropertyTypes() {
}
}
+ /**
+ * Prepares the target property types for the INSERT statement.
+ *
+ * This method determines which entity properties should be included in the INSERT statement
+ * based on the following rules:
+ *
+ * This method throws a JdbcException if a non-generated ID property has a null value.
+ */
protected void prepareTargetPropertyType() {
targetPropertyTypes = new ArrayList<>(entityType.getEntityPropertyTypes().size());
for (EntityPropertyType If the entity has a generated ID property, this method calls its preInsert method to
+ * generate or prepare the ID value before the INSERT operation.
+ */
protected void prepareIdValue() {
if (generatedIdPropertyType != null && idGenerationConfig != null) {
entity = generatedIdPropertyType.preInsert(entityType, entity, idGenerationConfig);
}
}
+ /**
+ * Prepares the version value for the entity before insertion.
+ *
+ * If the entity has a version property, this method initializes it to 1 for optimistic
+ * locking.
+ */
protected void prepareVersionValue() {
if (versionPropertyType != null) {
entity = versionPropertyType.setIfNecessary(entityType, entity, 1);
}
}
+ /**
+ * Prepares the SQL statement for this query.
+ *
+ * This method builds either a standard INSERT statement or an UPSERT statement based on the
+ * duplicate key handling strategy. It uses the dialect-specific SQL assemblers to generate the
+ * appropriate SQL syntax.
+ *
+ * If the duplicate key type is EXCEPTION, a standard INSERT statement is generated. Otherwise,
+ * an UPSERT statement is generated, unless the dialect supports MERGE statements and an identity
+ * key is included in the duplicate keys, in which case it falls back to a standard INSERT.
+ */
protected void prepareSql() {
Naming naming = config.getNaming();
Dialect dialect = config.getDialect();
@@ -158,6 +266,16 @@ protected void prepareSql() {
sql = builder.build(this::comment);
}
+ /**
+ * Assembles a standard INSERT SQL statement.
+ *
+ * This method creates an INSERT assembler context and uses the dialect-specific INSERT
+ * assembler to generate the SQL statement.
+ *
+ * @param builder the SQL builder
+ * @param naming the naming convention
+ * @param dialect the database dialect
+ */
private void assembleInsertSql(PreparedSqlBuilder builder, Naming naming, Dialect dialect) {
InsertAssemblerContext This method creates an UPSERT assembler context and uses the dialect-specific UPSERT
+ * assembler to generate the SQL statement. The UPSERT statement handles duplicate key scenarios
+ * according to the specified duplicate key type.
+ *
+ * @param builder the SQL builder
+ * @param naming the naming convention
+ * @param dialect the database dialect
+ */
private void assembleUpsertSql(PreparedSqlBuilder builder, Naming naming, Dialect dialect) {
List This method is called after executing the INSERT statement to retrieve and set
+ * auto-generated keys for the entity. It's only executed if auto-generated keys are supported for
+ * this query.
+ *
+ * @param statement the statement used for the INSERT operation
+ */
@Override
public void generateId(Statement statement) {
if (isAutoGeneratedKeysSupported()) {
@@ -202,11 +340,23 @@ public void generateId(Statement statement) {
}
}
+ /**
+ * Completes this query by executing post-insert processing.
+ *
+ * This method is called after the INSERT statement has been executed and any generated IDs
+ * have been retrieved.
+ */
@Override
public void complete() {
postInsert();
}
+ /**
+ * Executes post-insert entity processing.
+ *
+ * This method creates a post-insert context and calls the entity's postInsert method, allowing
+ * entity listeners to modify the entity after insertion.
+ */
protected void postInsert() {
AutoPostInsertContext This class extends AbstractPreInsertContext to add support for returning properties. It's
+ * used to pass information to entity listeners during the pre-insert phase.
+ *
+ * @param This class extends AbstractPostInsertContext to add support for returning properties. It's
+ * used to pass information to entity listeners during the post-insert phase.
+ *
+ * @param This class provides common functionality for entity-based modification operations such as
+ * INSERT, UPDATE, and DELETE. It handles:
+ *
+ * Subclasses implement specific modification operations by extending this class and providing
+ * operation-specific logic.
+ *
+ * @param This method performs basic preparation steps and validates that the dialect supports
+ * returning properties if they are specified.
+ *
+ * Subclasses should override this method to perform additional preparation steps, but must
+ * call {@code super.prepare()} first.
+ *
+ * @throws JdbcException if returning properties are specified but not supported by the dialect
+ */
@Override
public void prepare() {
super.prepare();
@@ -74,24 +125,60 @@ public void prepare() {
}
}
+ /**
+ * Prepares special property types for this query.
+ *
+ * This method initializes the ID, version, and tenant ID property types from the entity type
+ * metadata.
+ */
protected void prepareSpecialPropertyTypes() {
idPropertyTypes = entityType.getIdPropertyTypes();
versionPropertyType = entityType.getVersionPropertyType();
tenantIdPropertyType = entityType.getTenantIdPropertyType();
}
+ /**
+ * Validates that the entity has at least one ID property.
+ *
+ * This method is typically called by operations that require an ID property, such as UPDATE
+ * and DELETE.
+ *
+ * @throws JdbcException if the entity has no ID properties
+ */
protected void validateIdExistent() {
if (idPropertyTypes.isEmpty()) {
throw new JdbcException(Message.DOMA2022, entityType.getName());
}
}
+ /**
+ * Prepares query options.
+ *
+ * This method sets the query timeout from the configuration if it's not already set.
+ */
protected void prepareOptions() {
if (queryTimeout <= 0) {
queryTimeout = config.getQueryTimeout();
}
}
+ /**
+ * Determines whether a property should be included in the modification operation.
+ *
+ * This method applies the include and exclude filters to determine if a property should be
+ * targeted by the operation. The rules are:
+ *
+ * If this is set, only the specified properties will be included in the operation, unless they
+ * are also in the excluded property names.
+ *
+ * @param includedPropertyNames the property names to include
+ */
public void setIncludedPropertyNames(String... includedPropertyNames) {
this.includedPropertyNames = includedPropertyNames;
}
+ /**
+ * Sets the names of properties to be excluded from the modification operation.
+ *
+ * If this is set, the specified properties will be excluded from the operation.
+ *
+ * @param excludedPropertyNames the property names to exclude
+ */
public void setExcludedPropertyNames(String... excludedPropertyNames) {
this.excludedPropertyNames = excludedPropertyNames;
}
+ /**
+ * Sets the SQL log type for this query.
+ *
+ * @param sqlLogType the SQL log type
+ */
public void setSqlLogType(SqlLogType sqlLogType) {
this.sqlLogType = sqlLogType;
}
+ /**
+ * Sets the properties to be returned from the modification operation.
+ *
+ * This is used for database systems that support returning clause in modification statements.
+ *
+ * @param returning the returning properties
+ */
public void setReturning(ReturningProperties returning) {
this.returning = returning;
}
+ /** {@inheritDoc} */
@Override
public PreparedSql getSql() {
return sql;
}
+ /** {@inheritDoc} */
@Override
public boolean isOptimisticLockCheckRequired() {
return optimisticLockCheckRequired;
}
+ /** {@inheritDoc} */
@Override
public boolean isExecutable() {
return executable;
}
+ /** {@inheritDoc} */
@Override
public SqlExecutionSkipCause getSqlExecutionSkipCause() {
return sqlExecutionSkipCause;
}
+ /** {@inheritDoc} */
@Override
public boolean isAutoGeneratedKeysSupported() {
return autoGeneratedKeysSupported;
}
+ /** {@inheritDoc} */
@Override
public SqlLogType getSqlLogType() {
return sqlLogType;
}
+ /**
+ * Returns a string representation of this query.
+ *
+ * This method returns the string representation of the SQL statement if it has been prepared,
+ * or null otherwise.
+ *
+ * @return the string representation
+ */
@Override
public String toString() {
return sql != null ? sql.toString() : null;
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoModuleQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoModuleQuery.java
index e7b7d8dce..433a4635a 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoModuleQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoModuleQuery.java
@@ -23,24 +23,44 @@
import org.seasar.doma.jdbc.SqlLogType;
import org.seasar.doma.jdbc.SqlParameter;
+/**
+ * An abstract base class for queries that call database modules.
+ *
+ * This class provides common functionality for queries that call database stored procedures and
+ * functions. It handles parameter binding, module name qualification, and SQL generation.
+ */
public abstract class AutoModuleQuery extends AbstractQuery implements ModuleQuery {
+ /** The callable SQL for this module query. */
protected CallableSql sql;
+ /** The catalog name of the module. */
protected String catalogName;
+ /** The schema name of the module. */
protected String schemaName;
+ /** The name of the module. */
protected String moduleName;
+ /** The qualified name of the module. */
protected String qualifiedName;
+ /** Whether quotes are required for identifiers. */
protected boolean isQuoteRequired;
+ /** The parameters for the module call. */
protected final List This method builds the fully qualified name of the module using catalog, schema, and module
+ * names, applying quotes if required.
+ */
protected void prepareQualifiedName() {
Function This method sets default values for query timeout if not already set.
+ */
protected void prepareOptions() {
if (queryTimeout <= 0) {
queryTimeout = config.getQueryTimeout();
}
}
+ /** {@inheritDoc} */
@Override
public void complete() {}
+ /**
+ * Sets the catalog name of the module.
+ *
+ * @param catalogName the catalog name
+ */
public void setCatalogName(String catalogName) {
this.catalogName = catalogName;
}
+ /**
+ * Sets the schema name of the module.
+ *
+ * @param schemaName the schema name
+ */
public void setSchemaName(String schemaName) {
this.schemaName = schemaName;
}
+ /**
+ * Sets the name of the module.
+ *
+ * @param moduleName the module name
+ */
protected void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
+ /**
+ * Sets whether quotes are required for identifiers.
+ *
+ * @param isQuoteRequired {@code true} if quotes are required
+ */
public void setQuoteRequired(boolean isQuoteRequired) {
this.isQuoteRequired = isQuoteRequired;
}
+ /**
+ * Sets the SQL log type for this module query.
+ *
+ * @param sqlLogType the SQL log type
+ */
public void setSqlLogType(SqlLogType sqlLogType) {
this.sqlLogType = sqlLogType;
}
+ /**
+ * Adds a parameter to this module query.
+ *
+ * @param parameter the parameter to add
+ */
public void addParameter(SqlParameter parameter) {
parameters.add(parameter);
}
+ /** {@inheritDoc} */
@Override
public String getQualifiedName() {
return qualifiedName;
}
+ /** {@inheritDoc} */
@Override
public CallableSql getSql() {
return sql;
}
+ /** {@inheritDoc} */
@Override
public SqlLogType getSqlLogType() {
return sqlLogType;
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoMultiInsertQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoMultiInsertQuery.java
index c9a0e1c91..437dcac95 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoMultiInsertQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoMultiInsertQuery.java
@@ -42,21 +42,80 @@
import org.seasar.doma.jdbc.id.IdGenerationConfig;
import org.seasar.doma.message.Message;
+/**
+ * A query implementation for automatically inserting multiple entities into a database table.
+ *
+ * This class provides functionality to generate and execute SQL multi-row INSERT statements
+ * based on entity definitions. It handles various insert scenarios including:
+ *
+ * The query execution process includes:
+ *
+ * This method performs the following operations:
+ *
+ * This method creates a pre-insert context for each entity and calls the entity's preInsert
+ * method, allowing entity listeners to modify the entities before insertion.
+ */
protected void preInsert() {
ListIterator This method initializes the generated ID property type and its configuration, and determines
+ * if auto-generated keys are supported for this query.
+ *
+ * It also checks if the dialect supports auto-increment when inserting multiple rows, and
+ * throws an exception if not supported with IDENTITY generation type.
+ */
@Override
protected void prepareSpecialPropertyTypes() {
super.prepareSpecialPropertyTypes();
@@ -116,6 +190,21 @@ protected void prepareSpecialPropertyTypes() {
}
}
+ /**
+ * Prepares the target property types for the INSERT statement.
+ *
+ * This method determines which entity properties should be included in the INSERT statement
+ * based on the following rules:
+ *
+ * This method throws a JdbcException if a non-generated ID property has a null value.
+ */
protected void prepareTargetPropertyType() {
targetPropertyTypes = new ArrayList<>(entityType.getEntityPropertyTypes().size());
for (EntityPropertyType If the entities have a generated ID property, this method calls its preInsert method to
+ * generate or prepare the ID values before the INSERT operation.
+ */
protected void prepareIdValue() {
if (generatedIdPropertyType != null && idGenerationConfig != null) {
List If the entities have a version property, this method initializes it to 1 for optimistic
+ * locking.
+ */
protected void prepareVersionValue() {
if (versionPropertyType != null) {
ListIterator This method builds either a standard multi-row INSERT statement or an UPSERT statement based
+ * on the duplicate key handling strategy. It uses the dialect-specific SQL assemblers to generate
+ * the appropriate SQL syntax.
+ *
+ * If the duplicate key type is EXCEPTION, a standard INSERT statement is generated. Otherwise,
+ * an UPSERT statement is generated, unless the dialect supports MERGE statements and an identity
+ * key is included in the duplicate keys, in which case it falls back to a standard INSERT.
+ */
protected void prepareSql() {
Naming naming = config.getNaming();
Dialect dialect = config.getDialect();
@@ -186,6 +298,16 @@ protected void prepareSql() {
sql = builder.build(this::comment);
}
+ /**
+ * Assembles a standard multi-row INSERT SQL statement.
+ *
+ * This method creates a multi-insert assembler context and uses the dialect-specific
+ * multi-insert assembler to generate the SQL statement.
+ *
+ * @param builder the SQL builder
+ * @param naming the naming convention
+ * @param dialect the database dialect
+ */
private void assembleInsertSql(PreparedSqlBuilder builder, Naming naming, Dialect dialect) {
MultiInsertAssemblerContext This method creates an UPSERT assembler context and uses the dialect-specific UPSERT
+ * assembler to generate the SQL statement. The UPSERT statement handles duplicate key scenarios
+ * according to the specified duplicate key type.
+ *
+ * @param builder the SQL builder
+ * @param naming the naming convention
+ * @param dialect the database dialect
+ */
private void assembleUpsertSql(PreparedSqlBuilder builder, Naming naming, Dialect dialect) {
List This method is called after executing the INSERT statement to retrieve and set
+ * auto-generated keys for the entities. It's only executed if auto-generated keys are supported
+ * for this query.
+ *
+ * @param statement the statement used for the INSERT operation
+ */
@Override
public void generateId(Statement statement) {
if (isAutoGeneratedKeysSupported()) {
@@ -228,11 +370,23 @@ public void generateId(Statement statement) {
}
}
+ /**
+ * Completes this query by executing post-insert processing.
+ *
+ * This method is called after the INSERT statement has been executed and any generated IDs
+ * have been retrieved.
+ */
@Override
public void complete() {
postInsert();
}
+ /**
+ * Executes post-insert entity processing for each entity.
+ *
+ * This method creates a post-insert context for each entity and calls the entity's postInsert
+ * method, allowing entity listeners to modify the entities after insertion.
+ */
protected void postInsert() {
ListIterator This class extends AbstractPreInsertContext to add support for returning properties. It's
+ * used to pass information to entity listeners during the pre-insert phase.
+ *
+ * @param This class extends AbstractPostInsertContext to add support for returning properties. It's
+ * used to pass information to entity listeners during the post-insert phase.
+ *
+ * @param This class implements {@link ProcedureQuery} to provide functionality for calling database
+ * stored procedures. It handles parameter binding and SQL generation.
+ */
public class AutoProcedureQuery extends AutoModuleQuery implements ProcedureQuery {
+ /** {@inheritDoc} */
@Override
public void prepare() {
super.prepare();
@@ -32,12 +39,22 @@ public void prepare() {
assertNotNull(sql);
}
+ /**
+ * Prepares the SQL for this procedure query.
+ *
+ * This method builds the callable SQL statement for the procedure call.
+ */
protected void prepareSql() {
CallableSqlBuilder builder =
new CallableSqlBuilder(config, SqlKind.PROCEDURE, qualifiedName, parameters, sqlLogType);
sql = builder.build(this::comment);
}
+ /**
+ * Sets the procedure name.
+ *
+ * @param procedureName the procedure name
+ */
public void setProcedureName(String procedureName) {
setModuleName(procedureName);
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoUpdateQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoUpdateQuery.java
index ac8afdd45..6a8c6cfe9 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoUpdateQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoUpdateQuery.java
@@ -30,22 +30,49 @@
import org.seasar.doma.jdbc.entity.EntityPropertyType;
import org.seasar.doma.jdbc.entity.EntityType;
+/**
+ * A query implementation for automatically updating an entity.
+ *
+ * This class handles the automatic generation of SQL UPDATE statements based on entity
+ * definitions and configuration settings. It provides support for optimistic concurrency control
+ * through version properties, and allows customization of which properties are included in the
+ * update operation.
+ *
+ * @param This method prepares the query for execution by setting up the helper, calling pre-update
+ * hooks, preparing property types, validating entity IDs, setting up optimistic locking, and
+ * generating the SQL statement.
+ */
@Override
public void prepare() {
super.prepare();
@@ -61,6 +88,13 @@ public void prepare() {
assertNotNull(sql);
}
+ /**
+ * Sets up the helper for this query.
+ *
+ * This method initializes the {@link UpdateQueryHelper} with the current configuration and
+ * settings for property inclusion/exclusion, null handling, version handling, optimistic lock
+ * exception handling, and unchanged property handling.
+ */
protected void setupHelper() {
helper =
new UpdateQueryHelper<>(
@@ -74,6 +108,13 @@ protected void setupHelper() {
unchangedPropertyIncluded);
}
+ /**
+ * Executes pre-update processing for the entity.
+ *
+ * This method calls the entity's pre-update hooks with the appropriate context, allowing the
+ * entity to perform any necessary operations before the update is executed. If the pre-update
+ * hook returns a new entity instance, it will replace the current one.
+ */
protected void preUpdate() {
List This method sets up optimistic concurrency control based on the version property and
+ * configuration settings. If version checking is enabled and not suppressed, the query will be
+ * configured to check for optimistic lock violations.
+ */
protected void prepareOptimisticLock() {
if (!versionIgnored && versionPropertyType != null) {
if (!optimisticLockExceptionSuppressed) {
@@ -92,6 +140,13 @@ protected void prepareOptimisticLock() {
}
}
+ /**
+ * Prepares the target property types for this query.
+ *
+ * This method determines which entity properties will be included in the UPDATE statement
+ * based on the configuration and entity definition. If there are properties to update, the query
+ * is marked as executable.
+ */
protected void prepareTargetPropertyTypes() {
targetPropertyTypes = helper.getTargetPropertyTypes(entity);
if (!targetPropertyTypes.isEmpty()) {
@@ -100,6 +155,13 @@ protected void prepareTargetPropertyTypes() {
}
}
+ /**
+ * Prepares the SQL statement for this query.
+ *
+ * This method builds the SQL UPDATE statement using the dialect-specific assembler and the
+ * configured property types. It creates a context with all necessary information for the
+ * assembler to generate the appropriate SQL for the current database dialect.
+ */
protected void prepareSql() {
Dialect dialect = config.getDialect();
PreparedSqlBuilder builder = new PreparedSqlBuilder(config, SqlKind.UPDATE, sqlLogType);
@@ -124,6 +186,13 @@ protected void prepareSql() {
sql = builder.build(this::comment);
}
+ /**
+ * {@inheritDoc}
+ *
+ * This method increments the version number of the entity if optimistic concurrency control is
+ * enabled. The version property is used to detect concurrent modifications and prevent lost
+ * updates.
+ */
@Override
public void incrementVersion() {
if (!versionIgnored && versionPropertyType != null) {
@@ -131,11 +200,24 @@ public void incrementVersion() {
}
}
+ /**
+ * {@inheritDoc}
+ *
+ * This method completes the query execution by performing post-update processing.
+ */
@Override
public void complete() {
postUpdate();
}
+ /**
+ * Executes post-update processing for the entity.
+ *
+ * This method calls the entity's post-update hooks with the appropriate context, allowing the
+ * entity to perform any necessary operations after the update is executed. If the post-update
+ * hook returns a new entity instance, it will replace the current one. Finally, the current state
+ * of the entity is saved to track future changes.
+ */
protected void postUpdate() {
List This method uses a bitwise OR operation to combine the current setting with the new value,
+ * ensuring that once version checking is ignored, it remains ignored.
+ *
+ * @param versionIgnored true to ignore the version property, false otherwise
+ */
public void setVersionIgnored(boolean versionIgnored) {
this.versionIgnored |= versionIgnored;
}
+ /**
+ * Sets whether optimistic lock exceptions should be suppressed.
+ *
+ * @param optimisticLockExceptionSuppressed true to suppress optimistic lock exceptions, false
+ * otherwise
+ */
public void setOptimisticLockExceptionSuppressed(boolean optimisticLockExceptionSuppressed) {
this.optimisticLockExceptionSuppressed = optimisticLockExceptionSuppressed;
}
+ /**
+ * Sets whether unchanged properties should be included in the UPDATE statement.
+ *
+ * @param unchangedPropertyIncluded true to include unchanged properties, false otherwise
+ */
public void setUnchangedPropertyIncluded(Boolean unchangedPropertyIncluded) {
this.unchangedPropertyIncluded = unchangedPropertyIncluded;
}
+ /**
+ * A context class for pre-update processing.
+ *
+ * This class provides context information for entity pre-update hooks, including which
+ * properties are being changed and which properties should be returned.
+ *
+ * @param The entity is considered changed if there are any properties being updated.
+ */
@Override
public boolean isEntityChanged() {
return !changedPropertyNames.isEmpty();
}
+ /**
+ * {@inheritDoc}
+ *
+ * A property is considered changed if it is included in the set of properties targeted for
+ * update.
+ */
@Override
public boolean isPropertyChanged(String propertyName) {
validatePropertyDefined(propertyName);
return changedPropertyNames.contains(propertyName);
}
+ /** {@inheritDoc} */
@Override
public ReturningProperties getReturningProperties() {
return returningProperties;
}
}
+ /**
+ * A context class for post-update processing.
+ *
+ * This class provides context information for entity post-update hooks, including which
+ * properties were changed and which properties should be returned.
+ *
+ * @param A property is considered changed if it was included in the set of properties that were
+ * updated.
+ */
@Override
public boolean isPropertyChanged(String propertyName) {
validatePropertyDefined(propertyName);
return changedPropertyNames.contains(propertyName);
}
+ /** {@inheritDoc} */
@Override
public ReturningProperties getReturningProperties() {
return returningProperties;
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchDeleteQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchDeleteQuery.java
index 8d8e144e1..ea262ab67 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchDeleteQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchDeleteQuery.java
@@ -15,4 +15,14 @@
*/
package org.seasar.doma.jdbc.query;
+/**
+ * An interface for batch DELETE queries.
+ *
+ * This interface represents a query that performs batch DELETE operations. It extends {@link
+ * BatchModifyQuery} to inherit common batch data modification functionality while specializing for
+ * DELETE operations.
+ *
+ * Implementations of this interface handle the execution of multiple DELETE statements as a
+ * single batch operation for improved performance.
+ */
public interface BatchDeleteQuery extends BatchModifyQuery {}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchInsertQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchInsertQuery.java
index de1b705ba..1b6957c40 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchInsertQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchInsertQuery.java
@@ -17,10 +17,38 @@
import java.sql.Statement;
+/**
+ * An interface for batch INSERT queries.
+ *
+ * This interface represents a query that performs batch INSERT operations. It extends {@link
+ * BatchModifyQuery} to inherit common batch data modification functionality while specializing for
+ * INSERT operations.
+ *
+ * Implementations of this interface handle the execution of multiple INSERT statements as a
+ * single batch operation for improved performance, and provide methods for generating IDs for
+ * inserted rows.
+ */
public interface BatchInsertQuery extends BatchModifyQuery {
+ /**
+ * Determines if batch operations are supported for this query.
+ *
+ * Some database operations or configurations may not support batch processing. This method
+ * allows implementations to indicate whether batch operations can be used.
+ *
+ * @return true if batch operations are supported, false otherwise
+ */
boolean isBatchSupported();
+ /**
+ * Generates an ID for a single inserted row in the batch.
+ *
+ * This method is called after executing the batch to generate IDs for rows that use
+ * auto-generated keys or sequences.
+ *
+ * @param statement the statement used for the batch operation
+ * @param index the index of the element in the batch
+ */
void generateId(Statement statement, int index);
/**
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchModifyQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchModifyQuery.java
index 46c5855d0..fcd286df2 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchModifyQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchModifyQuery.java
@@ -20,23 +20,71 @@
import org.seasar.doma.jdbc.SqlExecutionSkipCause;
import org.seasar.doma.jdbc.SqlLogType;
+/**
+ * A query that performs batch operations to modify data in a database.
+ *
+ * This interface defines operations specific to batch data modification statements such as batch
+ * INSERT, UPDATE, and DELETE.
+ */
public interface BatchModifyQuery extends Query {
+ /**
+ * Returns the list of prepared SQL statements for this batch query.
+ *
+ * @return the list of prepared SQL statements
+ */
List This method is typically used for logging purposes.
+ *
+ * @return a representative prepared SQL statement
+ */
@Override
PreparedSql getSql();
+ /**
+ * Returns whether optimistic lock checking is required for this batch query.
+ *
+ * @return {@code true} if optimistic lock checking is required
+ */
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
boolean isOptimisticLockCheckRequired();
+ /**
+ * Returns whether auto-generated keys are supported for this batch query.
+ *
+ * @return {@code true} if auto-generated keys are supported
+ */
boolean isAutoGeneratedKeysSupported();
+ /**
+ * Returns whether this batch query is executable.
+ *
+ * @return {@code true} if this batch query is executable
+ */
boolean isExecutable();
+ /**
+ * Returns the cause if SQL execution should be skipped.
+ *
+ * @return the cause of SQL execution skip, or {@code null} if execution should not be skipped
+ */
SqlExecutionSkipCause getSqlExecutionSkipCause();
+ /**
+ * Returns the batch size for this query.
+ *
+ * @return the batch size
+ */
int getBatchSize();
+ /**
+ * Returns the SQL log type for this batch query.
+ *
+ * @return the SQL log type
+ */
SqlLogType getSqlLogType();
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchUpdateQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchUpdateQuery.java
index 449e3b91f..19083eb9e 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchUpdateQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchUpdateQuery.java
@@ -15,7 +15,25 @@
*/
package org.seasar.doma.jdbc.query;
+/**
+ * An interface for batch UPDATE queries.
+ *
+ * This interface represents a query that performs batch UPDATE operations. It extends {@link
+ * BatchModifyQuery} to inherit common batch data modification functionality while specializing for
+ * UPDATE operations.
+ *
+ * Implementations of this interface handle the execution of multiple UPDATE statements as a
+ * single batch operation for improved performance, and provide methods for handling optimistic
+ * concurrency control through version numbers.
+ */
public interface BatchUpdateQuery extends BatchModifyQuery {
+ /**
+ * Increments the version numbers for all entities in the batch.
+ *
+ * This method is called after executing the batch to update the version numbers in the entity
+ * objects, ensuring they match the values in the database after the update. This is important for
+ * optimistic concurrency control.
+ */
void incrementVersions();
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchUpdateQueryHelper.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchUpdateQueryHelper.java
index b8344ad1e..bffff9708 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchUpdateQueryHelper.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/BatchUpdateQueryHelper.java
@@ -25,20 +25,42 @@
import org.seasar.doma.jdbc.entity.EntityType;
import org.seasar.doma.jdbc.entity.Property;
+/**
+ * A helper class for batch update queries. This class provides utility methods for handling entity
+ * properties in batch update operations.
+ *
+ * @param This class extends {@link AbstractCreateQuery} to provide functionality for creating BLOB
+ * objects. It uses the JDBC connection's createBlob method to create a new empty BLOB instance.
+ */
public class BlobCreateQuery extends AbstractCreateQuery This class extends {@link AbstractCreateQuery} to provide functionality for creating CLOB
+ * objects. It uses the JDBC connection's createClob method to create a new empty CLOB instance.
+ */
public class ClobCreateQuery extends AbstractCreateQuery This class extends {@link AbstractSelectQuery} to provide functionality for transforming a
+ * SELECT query into a COUNT query. It uses the database dialect to transform the SQL node for
+ * counting.
+ */
public class CountQuery extends AbstractSelectQuery {
+ /** The SQL node representing the original SELECT query. */
protected SqlNode sqlNode;
+ /** {@inheritDoc} */
@Override
public boolean isResultEnsured() {
return true;
}
+ /** {@inheritDoc} */
@Override
public boolean isResultMappingEnsured() {
return false;
}
+ /** {@inheritDoc} */
@Override
public FetchType getFetchType() {
return FetchType.LAZY;
}
+ /** {@inheritDoc} */
@Override
public void prepare() {
super.prepare();
assertNotNull(sqlNode);
}
+ /** {@inheritDoc} */
@Override
protected void prepareSql() {
SqlNode transformedSqlNode = config.getDialect().transformSelectSqlNodeForGettingCount(sqlNode);
@@ -65,11 +78,17 @@ protected void prepareSql() {
sql = sqlBuilder.build(transformedSqlNode, this::comment);
}
+ /** {@inheritDoc} */
@Override
public void complete() {
// do nothing
}
+ /**
+ * Sets the SQL node representing the original SELECT query.
+ *
+ * @param sqlNode the SQL node
+ */
public void setSqlNode(SqlNode sqlNode) {
this.sqlNode = sqlNode;
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/CreateQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/CreateQuery.java
index c0010286d..aa45f243e 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/CreateQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/CreateQuery.java
@@ -18,7 +18,21 @@
import java.sql.Connection;
import java.sql.SQLException;
+/**
+ * A query that creates a database resource.
+ *
+ * This interface is used to create JDBC resources such as BLOB, CLOB, Array, etc.
+ *
+ * @param This interface is responsible for generating the SQL for DELETE operations. Implementations of
+ * this interface handle the construction of DELETE statements, including the WHERE clause and any
+ * other necessary SQL components.
+ */
public interface DeleteAssembler {
+ /**
+ * Assembles the DELETE query.
+ *
+ * This method generates the SQL for the DELETE operation, including the table name, WHERE
+ * clause, and any other required SQL components.
+ */
void assemble();
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/DeleteAssemblerContext.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/DeleteAssemblerContext.java
index e0e19d75c..55e74a789 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/DeleteAssemblerContext.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/DeleteAssemblerContext.java
@@ -31,17 +31,50 @@
* @param This interface represents a query that performs DELETE operations. It extends {@link
+ * ModifyQuery} to inherit common data modification functionality while specializing for DELETE
+ * operations.
+ *
+ * Implementations of this interface handle the execution of DELETE statements, including the
+ * construction of the WHERE clause and handling of optimistic concurrency control.
+ */
public interface DeleteQuery extends ModifyQuery {}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/DuplicateKeyType.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/DuplicateKeyType.java
index 5835ad3c3..55469bddc 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/DuplicateKeyType.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/DuplicateKeyType.java
@@ -15,10 +15,35 @@
*/
package org.seasar.doma.jdbc.query;
-/** Retrieves the type of the duplicate key when inserting a new entity. */
+/**
+ * Specifies how to handle duplicate key violations during insert operations.
+ *
+ * This enum defines the behavior when an insert operation would violate a unique constraint in
+ * the database.
+ */
public enum DuplicateKeyType {
+ /**
+ * Updates the existing row when a duplicate key is encountered.
+ *
+ * This option causes the database to perform an update on the existing row instead of
+ * inserting a new row when a duplicate key is detected.
+ */
UPDATE,
+
+ /**
+ * Ignores the insert operation when a duplicate key is encountered.
+ *
+ * This option causes the database to silently ignore the insert operation without raising an
+ * error when a duplicate key is detected.
+ */
IGNORE,
+
+ /**
+ * Throws an exception when a duplicate key is encountered.
+ *
+ * This option causes the database to raise an error when a duplicate key is detected, which is
+ * the default behavior for most databases.
+ */
EXCEPTION,
;
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/FunctionQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/FunctionQuery.java
index 1c4aafebf..12b07a549 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/FunctionQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/FunctionQuery.java
@@ -15,7 +15,27 @@
*/
package org.seasar.doma.jdbc.query;
+/**
+ * An interface for database function queries.
+ *
+ * This interface represents a query that calls a database function. It extends {@link
+ * ModuleQuery} to inherit common database module functionality while specializing for function
+ * calls that return a result.
+ *
+ * Implementations of this interface handle the execution of database function calls, including
+ * parameter binding and result retrieval.
+ *
+ * @param This method is called after executing the function to retrieve the result value. The result
+ * type depends on the function's return type and the Java type mapping.
+ *
+ * @return the function result
+ */
RESULT getResult();
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertAssembler.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertAssembler.java
index 9e08bd53f..51b66b724 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertAssembler.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertAssembler.java
@@ -15,6 +15,19 @@
*/
package org.seasar.doma.jdbc.query;
+/**
+ * An interface for assembling INSERT queries.
+ *
+ * This interface is responsible for generating the SQL for INSERT operations. Implementations of
+ * this interface handle the construction of INSERT statements, including the column list, values
+ * clause, and any other necessary SQL components.
+ */
public interface InsertAssembler {
+ /**
+ * Assembles the INSERT query.
+ *
+ * This method generates the SQL for the INSERT operation, including the table name, column
+ * list, values clause, and any other required SQL components.
+ */
void assemble();
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertQuery.java
index fc91a821f..850650fde 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertQuery.java
@@ -17,7 +17,27 @@
import java.sql.Statement;
+/**
+ * An interface for INSERT queries.
+ *
+ * This interface represents a query that performs INSERT operations. It extends {@link
+ * ModifyQuery} to inherit common data modification functionality while specializing for INSERT
+ * operations.
+ *
+ * Implementations of this interface handle the execution of INSERT statements, including the
+ * construction of the column list, values clause, and generation of auto-generated keys or sequence
+ * values.
+ */
public interface InsertQuery extends ModifyQuery {
+ /**
+ * Generates an ID for the inserted row.
+ *
+ * This method is called after executing the INSERT statement to retrieve and set
+ * auto-generated keys or sequence values for the entity. It's typically used for primary key
+ * generation strategies like identity columns or sequences.
+ *
+ * @param statement the statement used for the INSERT operation
+ */
void generateId(Statement statement);
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertRow.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertRow.java
index 214742052..97eb8b69b 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertRow.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/InsertRow.java
@@ -19,13 +19,26 @@
import java.util.List;
import java.util.Objects;
+/**
+ * Represents a row to be inserted in an INSERT statement.
+ *
+ * This class holds a list of values for a single row in a batch or multi-row insert operation.
+ * It implements {@link Iterable} to allow iteration over the values in the row.
+ */
public class InsertRow implements Iterable This interface defines operations specific to data modification statements such as INSERT,
+ * UPDATE, and DELETE.
+ */
public interface ModifyQuery extends Query {
+ /**
+ * Returns the prepared SQL for this modification query.
+ *
+ * @return the prepared SQL
+ */
@Override
PreparedSql getSql();
+ /**
+ * Returns whether optimistic lock checking is required for this query.
+ *
+ * @return {@code true} if optimistic lock checking is required
+ */
boolean isOptimisticLockCheckRequired();
+ /**
+ * Returns whether auto-generated keys are supported for this query.
+ *
+ * @return {@code true} if auto-generated keys are supported
+ */
boolean isAutoGeneratedKeysSupported();
+ /**
+ * Returns whether this query is executable.
+ *
+ * @return {@code true} if this query is executable
+ */
boolean isExecutable();
+ /**
+ * Returns the cause if SQL execution should be skipped.
+ *
+ * @return the cause of SQL execution skip, or {@code null} if execution should not be skipped
+ */
SqlExecutionSkipCause getSqlExecutionSkipCause();
+ /**
+ * Returns the SQL log type for this query.
+ *
+ * @return the SQL log type
+ */
SqlLogType getSqlLogType();
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/ModuleQuery.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/ModuleQuery.java
index 17f9b745e..611433889 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/ModuleQuery.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/ModuleQuery.java
@@ -18,12 +18,32 @@
import org.seasar.doma.jdbc.CallableSql;
import org.seasar.doma.jdbc.SqlLogType;
+/**
+ * A query that calls a database module such as a stored procedure or function.
+ *
+ * This interface defines operations specific to database module calls.
+ */
public interface ModuleQuery extends Query {
+ /**
+ * Returns the callable SQL for this module query.
+ *
+ * @return the callable SQL
+ */
@Override
CallableSql getSql();
+ /**
+ * Returns the qualified name of the database module.
+ *
+ * @return the qualified name
+ */
String getQualifiedName();
+ /**
+ * Returns the SQL log type for this module query.
+ *
+ * @return the SQL log type
+ */
SqlLogType getSqlLogType();
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/MultiInsertAssemblerContext.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/MultiInsertAssemblerContext.java
index b4453b04f..d7e782521 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/MultiInsertAssemblerContext.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/MultiInsertAssemblerContext.java
@@ -47,6 +47,7 @@ public class MultiInsertAssemblerContext This class extends {@link AbstractCreateQuery} to provide functionality for creating NCLOB
+ * objects. It uses the JDBC connection's createNClob method to create a new empty NCLOB instance
+ * that can store Unicode character data.
+ */
public class NClobCreateQuery extends AbstractCreateQuery This interface represents a query that calls a database stored procedure. It extends {@link
+ * ModuleQuery} to inherit common database module functionality while specializing for procedure
+ * calls that don't return a result.
+ *
+ * Implementations of this interface handle the execution of database procedure calls, including
+ * parameter binding and handling of OUT and INOUT parameters. Unlike {@link FunctionQuery},
+ * procedures typically don't return a value directly, but may modify OUT parameters or perform
+ * database operations.
+ */
public interface ProcedureQuery extends ModuleQuery {}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/Query.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/Query.java
index 214eafe0c..e0accb6e2 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/Query.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/Query.java
@@ -19,23 +19,68 @@
import org.seasar.doma.jdbc.Config;
import org.seasar.doma.jdbc.Sql;
+/**
+ * The base interface for all query types.
+ *
+ * This interface defines the common operations for all database queries in Doma.
+ */
public interface Query {
+ /**
+ * Returns the SQL object that represents the query.
+ *
+ * @return the SQL object
+ */
Sql> getSql();
+ /**
+ * Returns the class name where the query is defined.
+ *
+ * @return the class name
+ */
String getClassName();
+ /**
+ * Returns the method name where the query is defined.
+ *
+ * @return the method name
+ */
String getMethodName();
+ /**
+ * Returns the method object where the query is defined.
+ *
+ * @return the method object
+ */
Method getMethod();
+ /**
+ * Returns the configuration for this query.
+ *
+ * @return the configuration
+ */
Config getConfig();
+ /**
+ * Returns the query timeout in seconds.
+ *
+ * @return the query timeout
+ */
int getQueryTimeout();
+ /** Prepares this query for execution. This method must be called before the query is executed. */
void prepare();
+ /**
+ * Completes this query after execution. This method must be called after the query is executed.
+ */
void complete();
+ /**
+ * Adds a comment to the SQL statement.
+ *
+ * @param sql the SQL statement
+ * @return the SQL statement with the comment
+ */
String comment(String sql);
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryOperand.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryOperand.java
index 95ce45354..bcd550042 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryOperand.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryOperand.java
@@ -19,53 +19,117 @@
import org.seasar.doma.jdbc.InParameter;
import org.seasar.doma.jdbc.entity.EntityPropertyType;
+/**
+ * An interface representing an operand in a database query.
+ *
+ * This interface provides a way to represent different types of operands that can be used in
+ * database queries, such as parameters and property references. It follows the visitor pattern to
+ * allow operations on these operands without modifying their structure.
+ */
public interface QueryOperand {
+ /**
+ * Returns the entity property type associated with this operand.
+ *
+ * @return the entity property type
+ */
EntityPropertyType, ?> getEntityPropertyType();
+ /**
+ * Accepts a visitor to perform operations on this operand.
+ *
+ * @param visitor the visitor to accept
+ */
void accept(QueryOperand.Visitor visitor);
+ /**
+ * A parameter operand that contains both a property type and an input parameter.
+ *
+ * This class represents a parameter value that will be bound to a query.
+ */
final class Param implements QueryOperand {
+ /** The entity property type. */
public final EntityPropertyType, ?> propertyType;
+
+ /** The input parameter to be bound to the query. */
public final InParameter> inParameter;
+ /**
+ * Constructs a new parameter operand.
+ *
+ * @param propertyType the entity property type
+ * @param inParameter the input parameter
+ * @throws NullPointerException if either parameter is null
+ */
public Param(EntityPropertyType, ?> propertyType, InParameter> inParameter) {
this.propertyType = Objects.requireNonNull(propertyType);
this.inParameter = Objects.requireNonNull(inParameter);
}
+ /** {@inheritDoc} */
@Override
public EntityPropertyType, ?> getEntityPropertyType() {
return propertyType;
}
+ /** {@inheritDoc} */
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
+ /**
+ * A property operand that references an entity property.
+ *
+ * This class represents a reference to an entity property in a query.
+ */
final class Prop implements QueryOperand {
+ /** The entity property type. */
public final EntityPropertyType, ?> propertyType;
+ /**
+ * Constructs a new property operand.
+ *
+ * @param propertyType the entity property type
+ * @throws NullPointerException if the property type is null
+ */
public Prop(EntityPropertyType, ?> propertyType) {
this.propertyType = Objects.requireNonNull(propertyType);
}
+ /** {@inheritDoc} */
@Override
public EntityPropertyType, ?> getEntityPropertyType() {
return propertyType;
}
+ /** {@inheritDoc} */
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
+ /**
+ * A visitor interface for {@link QueryOperand} implementations.
+ *
+ * This interface follows the visitor pattern to allow operations on different types of query
+ * operands without modifying their structure.
+ */
interface Visitor {
+ /**
+ * Visits a parameter operand.
+ *
+ * @param param the parameter operand to visit
+ */
void visit(QueryOperand.Param param);
+ /**
+ * Visits a property operand.
+ *
+ * @param prop the property operand to visit
+ */
void visit(QueryOperand.Prop prop);
}
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryOperandPair.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryOperandPair.java
index 2058b10dc..d2265ed1c 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryOperandPair.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryOperandPair.java
@@ -17,19 +17,46 @@
import java.util.Objects;
+/**
+ * Represents a pair of query operands.
+ *
+ * This class is used to associate two operands together, typically for operations that require
+ * comparing or mapping values between them, such as in UPDATE statements where columns are set to
+ * new values.
+ */
public class QueryOperandPair {
+ /** The left operand in the pair. */
private final QueryOperand left;
+
+ /** The right operand in the pair. */
private final QueryOperand right;
+ /**
+ * Constructs a new {@code QueryOperandPair} with the specified operands.
+ *
+ * @param left the left operand
+ * @param right the right operand
+ * @throws NullPointerException if either operand is null
+ */
public QueryOperandPair(QueryOperand left, QueryOperand right) {
this.left = Objects.requireNonNull(left);
this.right = Objects.requireNonNull(right);
}
+ /**
+ * Returns the left operand.
+ *
+ * @return the left operand
+ */
public QueryOperand getLeft() {
return left;
}
+ /**
+ * Returns the right operand.
+ *
+ * @return the right operand
+ */
public QueryOperand getRight() {
return right;
}
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryUtil.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryUtil.java
index 05ae05958..8eebf6f2e 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryUtil.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/QueryUtil.java
@@ -19,8 +19,24 @@
import org.seasar.doma.GenerationType;
import org.seasar.doma.jdbc.entity.GeneratedIdPropertyType;
+/**
+ * Utility class for query operations.
+ *
+ * This class provides utility methods for query processing and validation.
+ */
final class QueryUtil {
+ /**
+ * Determines if an identity key is included in the duplicate keys.
+ *
+ * This method checks whether a generated identity property is part of the specified duplicate
+ * key names. If no duplicate key names are specified, it assumes the identity key is included.
+ *
+ * @param generatedIdPropertyType the generated ID property type
+ * @param duplicateKeyNames the names of columns that may cause duplicate key violations
+ * @return {@code true} if the identity key is included in the duplicate keys, {@code false}
+ * otherwise
+ */
static boolean isIdentityKeyIncludedInDuplicateKeys(
GeneratedIdPropertyType, ?, ?> generatedIdPropertyType, String[] duplicateKeyNames) {
if (generatedIdPropertyType == null) {
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/ReturningProperties.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/ReturningProperties.java
index 54561986d..b3fe071a4 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/ReturningProperties.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/ReturningProperties.java
@@ -21,7 +21,23 @@
import org.seasar.doma.jdbc.entity.EntityPropertyType;
import org.seasar.doma.jdbc.entity.EntityType;
-/** Represents returning properties. */
+/**
+ * An interface that represents properties to be returned from database operations.
+ *
+ * This interface is used to specify which entity properties should be returned from database
+ * operations that support returning clauses, such as INSERT, UPDATE, or DELETE with RETURNING. It
+ * provides a way to select specific properties or all properties to be included in the returning
+ * clause.
+ *
+ * The interface includes predefined instances for common cases:
+ *
+ * Custom implementations can be created to return specific subsets of properties.
+ */
public interface ReturningProperties {
/** A predefined instance of {@link ReturningProperties} that represents no properties. */
diff --git a/doma-core/src/main/java/org/seasar/doma/jdbc/query/ReturningPropertyNames.java b/doma-core/src/main/java/org/seasar/doma/jdbc/query/ReturningPropertyNames.java
index 5211eb365..1e85801a9 100644
--- a/doma-core/src/main/java/org/seasar/doma/jdbc/query/ReturningPropertyNames.java
+++ b/doma-core/src/main/java/org/seasar/doma/jdbc/query/ReturningPropertyNames.java
@@ -20,16 +20,33 @@
import org.seasar.doma.jdbc.entity.EntityPropertyType;
import org.seasar.doma.jdbc.entity.EntityType;
+/**
+ * A class that resolves property names to entity property types for returning clauses.
+ *
+ * This class implements {@link ReturningProperties} to provide a way to specify which entity
+ * properties should be returned from database operations using property names. It supports
+ * including specific properties and excluding others.
+ */
public class ReturningPropertyNames implements ReturningProperties {
+ /** The names of properties to include in the returning clause. */
private final List
+ *
+ *
+ *
+ *
+ *
+ * @param
+ *
+ */
@Override
public void prepare() {
super.prepare();
@@ -71,6 +128,12 @@ public void prepare() {
assertNotNull(sql);
}
+ /**
+ * Executes pre-insert entity processing.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * @param name the property name to check
+ * @return true if the property should be included, false otherwise
+ */
protected boolean isTargetPropertyName(String name) {
if (includedPropertyNames.length > 0) {
for (String includedName : includedPropertyNames) {
@@ -117,60 +204,111 @@ protected boolean isTargetPropertyName(String name) {
return true;
}
+ /**
+ * Sets the entity instance to be modified.
+ *
+ * @param entity the entity instance
+ */
public void setEntity(ENTITY entity) {
this.entity = entity;
}
+ /**
+ * Returns the entity instance to be modified.
+ *
+ * @return the entity instance
+ */
public ENTITY getEntity() {
return entity;
}
+ /**
+ * Sets the names of properties to be included in the modification operation.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * @param
+ *
+ */
@Override
public void prepare() {
super.prepare();
@@ -84,6 +143,12 @@ public void prepare() {
assertNotNull(sql);
}
+ /**
+ * Executes pre-insert entity processing for each entity.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *