Update

Annotate DAO methods with @Update to execute update operations.

@Dao
public interface EmployeeDao {
    @Update
    int update(Employee employee);

    @Update
    Result<ImmutableEmployee> update(ImmutableEmployee employee);
}

By default, the UPDATE statement is automatically generated. You can map to an arbitrary SQL file by setting the sqlFile property to true in the @Update annotation.

If an entity listener is specified for the entity class parameter, the preUpdate method of the entity listener is called before executing the update. Similarly, the postUpdate method of the entity listener is called after executing the update.

Return value

When using the returning property

See returning.

When not using the returning property

If the parameter is an immutable entity class, the return value must be an org.seasar.doma.jdbc.Result with an entity class as its element.

If the above condition is not satisfied, the return value must be an int representing the number of updated rows.

Update by auto generated SQL

The parameter type must be an entity class. Only one parameter can be specified. The parameter must not be null.

@Update
int update(Employee employee);

@Update
Result<ImmutableEmployee> update(ImmutableEmployee employee);

Version number and optimistic concurrency control in auto generated SQL

Optimistic concurrency control is executed if the following conditions are met:

  • The entity class parameter has a property that is annotated with @Version

  • The ignoreVersion element in the @Update annotation is false

When optimistic concurrency control is enabled, the version number is included with the identifier in the update condition and is incremented by 1. If the update count is 0, an OptimisticLockException is thrown to indicate optimistic concurrency control failure. If the update count is not 0, no OptimisticLockException is thrown and the version property in the entity is incremented by 1.

ignoreVersion

If the ignoreVersion property in the @Update annotation is set to true, the version number is not included in the update condition but is included in the SET clauses of the UPDATE statement. The version number is updated by setting a value at the application level. In this case, an OptimisticLockException is not thrown even if the update count is 0.

@Update(ignoreVersion = true)
int update(Employee employee);

suppressOptimisticLockException

When the suppressOptimisticLockException property in the @Update annotation is set to true, if a property annotated with @Version exists, the version number is included in the update condition and incremented by 1. An OptimisticLockException is not thrown even if the update count is 0. However, the version property value in the entity is still incremented by 1.

@Update(suppressOptimisticLockException = true)
int update(Employee employee);

Control updating target property

updatable

Properties annotated with @Column that have their updatable property set to false are excluded from the update targets.

exclude

Properties specified in the exclude property of the @Update annotation are excluded from the update targets. Even if the updatable property in the @Column annotation is set to true, properties listed in the exclude property will not be updated.

@Update(exclude = {"name", "salary"})
int update(Employee employee);

include

Only properties specified in the include property of the @Update annotation will be updated. If the same property appears in both the include and exclude properties of @Update, it will not be updated. Even if a property is listed in the include property, it will not be updated if its updatable property in the @Column annotation is set to false.

@Update(include = {"name", "salary"})
int update(Employee employee);

excludeNull

When the excludeNull property of the @Update annotation is set to true, properties with a value of null will not be updated. This takes precedence over other settings - even if a property’s updatable attribute in its @Column annotation is set to true or the property is listed in the include property of the @Update annotation, it will not be updated if its value is null.

@Update(excludeNull = true)
int update(Employee employee);

includeUnchanged

This property is only effective if the entity class being updated contains a property annotated with @OriginalStates.

When set to true, all properties in the entity will be updated. This means all corresponding columns will be included in the SET clauses of the UPDATE statement.

When set to false, only properties that have changed since the entity was loaded will be updated. Only the columns corresponding to these modified properties will be included in the SET clauses of the UPDATE statement.

@Update(includeUnchanged = true)
int update(Employee employee);

returning

By specifying @Returning in the returning property, you can generate SQL with the UPDATE .. RETURNING clause.

@Dao
public interface EmployeeDao {
    @Update(returning = @Returning)
    Employee update(Employee employee);

    @Update(returning = @Returning(include = { "employeeId", "version" }))
    Employee updateReturningIdAndVersion(Employee employee);

    @Update(returning = @Returning(exclude = { "password" }))
    Employee updateReturningExceptPassword(Employee employee);

    @Update(returning = @Returning, suppressOptimisticLockException = true)
    Optional<Employee> updateOrIgnore(Employee employee);
}

You can use the include element of @Returning to specify which entity properties (corresponding to database columns) should be returned by the RETURNING clause. Alternatively, you can use the exclude element to specify which properties should be excluded from the results. If a property appears in both the include and exclude elements, it will not be returned.

The return type must be either an entity class or an Optional containing an entity class as its element.

Note

Only H2 Database, PostgreSQL, SQL Server, and SQLite Dialects support this feature.

Update by SQL file

To execute an update using an SQL file, set the sqlFile property to true in the @Update annotation and prepare an SQL file that corresponds to the method.

Note

When updating via SQL file, the rules differ depending on whether you use Population directive.

Case of using the populate directive

The first parameter must be an entity class. There is no limit on the number of parameters you can specify. You can pass null for parameters of basic types or domain classes. For all other parameter types, null values are not allowed.

@Update(sqlFile = true)
int update(Employee employee, BigDecimal salary);

@Update(sqlFile = true)
Result<ImmutableEmployee> update(ImmutableEmployee employee, BigDecimal salary);

For example, you would write an SQL file like the one below to correspond to the above method:

update employee set /*%populate*/ id = id where salary > /* salary */0

The rules for controlling update target properties are the same as in Update by auto generated SQL.

Case of not using the populate directive

You can use any type as a parameter. There is no limit on the number of parameters you can specify. You can pass null for parameters of basic types or domain classes. For all other parameter types, null values are not allowed.

@Update(sqlFile = true)
int update(Employee employee);

@Update(sqlFile = true)
Result<ImmutableEmployee> update(ImmutableEmployee employee);

For example, you would write an SQL file like the one below to correspond to the above method:

update employee set name = /* employee.name */'hoge', salary = /* employee.salary */100
where id = /* employee.id */0

The exclude, include, excludeNull, and includeUnchanged properties within the @Update annotation are not referenced when updating via SQL file.

Version number and optimistic concurrency control in SQL file

Optimistic concurrency control is executed if the following conditions are met:

  • An entity class is included in the parameters

  • The leftmost entity class parameter has a property annotated with @Version

  • The ignoreVersion element in the @Update annotation is false

However, writing SQL for optimistic concurrency control is the application developer’s responsibility. For example, in the SQL below, you must include the version number in the WHERE clause and increment it by 1 in the SET clause.

update EMPLOYEE set DELETE_FLAG = 1, VERSION = /* employee.version */1 + 1
where ID = /* employee.id */1 and VERSION = /* employee.version */1

If this SQL statement’s update count is 0, an OptimisticLockException is thrown to indicate optimistic concurrency control failure. If the update count is not 0, no OptimisticLockException is thrown and the version property in the entity is incremented by 1.

ignoreVersion

If the ignoreVersion property of the @Update annotation is set to true, no OptimisticLockException will be thrown even if the update count is 0. Additionally, the version property value in the entity remains unchanged.

@Update(sqlFile = true, ignoreVersion = true)
int update(Employee employee);
suppressOptimisticLockException

If the suppressOptimisticLockException property of the @Update annotation is set to true, no OptimisticLockException will be thrown even if the update count is 0. However, the version property value in the entity will still be incremented by 1.

@Update(sqlFile = true, suppressOptimisticLockException = true)
int update(Employee employee);

Unique constraint violation

A UniqueConstraintException is thrown if a unique constraint violation occurs, regardless of whether an SQL file is used or not.

Query timeout

You can specify the query timeout in seconds using the queryTimeout property in the @Update annotation.

@Update(queryTimeout = 10)
int update(Employee employee);

This specification applies regardless of whether an SQL file is used or not. If the queryTimeout property is not set, the query timeout specified in Configuration is used.

SQL log output format

You can specify the SQL log output format using the sqlLog property in the @Update annotation.

@Update(sqlLog = SqlLogType.RAW)
int update(Employee employee);

SqlLogType.RAW indicates that the log output will contain the SQL with binding parameters.