枚举类 QueryReason

java.lang.Object
java.lang.Enum<QueryReason>
org.babyfish.jimmer.sql.ast.impl.mutation.QueryReason
所有已实现的接口:
Serializable, Comparable<QueryReason>, Constable

public enum QueryReason extends Enum<QueryReason>
Jimmer's save command supports upsert operations and tries to leverage the database's native upsert capabilities whenever possible, rather than executing an additional select statement to determine whether the subsequent operation should be an insert or update.

However, the database's native upsert capability is not suitable for all situations. When necessary, Jimmer may still execute a select statement within the save command. When this occurs, this enumeration can inform users why this is happening.

In addition to the save command, delete commands and delete statements may also need to execute some select statements in certain scenarios. This enumeration includes these cases as well.

  • 嵌套类概要

    从类继承的嵌套类/接口 java.lang.Enum

    Enum.EnumDesc<E extends Enum<E>>
  • 枚举常量概要

    枚举常量
    枚举常量
    说明
    Direct use of a delete statement, but upon discovering that the object being deleted has child objects and the user requires Jimmer to handle these child objects, the delete statement is converted into a delete command
    Associated objects with only Id properties are not cascade-saved and merely serve as dependencies for the current entity.
    When explicitly modifying objects based on Key properties, the underlying database lacks the ability to return the ids of existing objects, or this capability has not yet been integrated into Jimmer.
    When explicitly updating objects based on Key properties, the objects being saved do not have any other properties that need to be modified.
    Attempting to save an object without Id property, but the corresponding entity has not been configured with identity generation strategy.
    The entity type being operated on has been applied with a DraftInterceptor to facilitate data adjustment before being saved to the database.
    The current entity type being operated on is annotated with KeyUniqueConstraint.
    The current database is MySQL, if there save object does not have Id property, Jimmer uses an insert ... on duplicate update... statement based on key properties, for example
     
    When saving objects without id properties, Jimmer will make the upsert statement determine whether existing data exists in the database based on Key properties and LogicalDeleted property.
    The current database does not support mixing optimistic locking checks in upsert operations (so far, among the dialects implemented in Jimmer, only Postgres supports this)
    If the associated property is OneToMany association or an inverse OneToOne (Inverse means mappedBy is specified, eg: @OneToOne(mappedBy="...")) association, then the associated objects are child objects of the current object.
    Jimmer will delete objects in any of the following situations: Direct use of the delete command Direct use of a delete statement, but upon discovering that the object being deleted has child objects and the user requires Jimmer to handle these child objects, the delete statement is converted into a delete command Using a save command, but Jimmer determines that the current object has discarded some associated objects, requiring dissociation operations for these no longer needed associated objects, and the corresponding dissociation operation is configured for deletion
    In-transaction trigger is enabled, meaning Jimmer's trigger type is set to `TRANSACTION_ONLY` or `BOTH`.
    Sometimes, Jimmer requires multi-column in expression, i.e.,
    The current database does not support upsert operations, or its upsert operation has not been integrated with Jimmer
  • 方法概要

    修饰符和类型
    方法
    说明
    返回带有指定名称的该类的枚举常量。
    static QueryReason[]
    返回包含该枚举类的常量的数组, 顺序与声明这些常量的顺序相同

    从类继承的方法 java.lang.Object

    getClass, notify, notifyAll, wait, wait, wait
  • 枚举常量详细资料

    • NONE

      public static final QueryReason NONE
    • TRIGGER

      public static final QueryReason TRIGGER
      In-transaction trigger is enabled, meaning Jimmer's trigger type is set to `TRANSACTION_ONLY` or `BOTH`.

      This mechanism is highly similar to AT mode of Apache Seata, where an additional select statement is executed before modifying the data to get the old values, simulating database trigger-like functionality before the transaction is committed.

      No handling is required for this situation, as this is precisely what you need.

    • INTERCEPTOR

      public static final QueryReason INTERCEPTOR
      The entity type being operated on has been applied with a DraftInterceptor to facilitate data adjustment before being saved to the database.

      The DraftInterceptor's functionality is relatively powerful, capable of informing developers whether an object is about to be saved or modified. At this point, the database has not been modified, so a select statement must be used to determine whether the subsequent operation is an insert or update and to notify the user.

      If you don't want this behavior, you can use a DraftHandler instead. Its functionality is similar to DraftInterceptor but relatively weaker, not distinguishing between insert and update scenarios, thus avoiding this issue.

    • CHECKING

      public static final QueryReason CHECKING
      Associated objects with only Id properties are not cascade-saved and merely serve as dependencies for the current entity.

      However, users can choose to validate whether these id-only associated objects represent valid data before saving the current object. This is particularly useful for ForeignKeyType.FAKE foreign keys.

    • TOO_DEEP

      public static final QueryReason TOO_DEEP
      Jimmer will delete objects in any of the following situations:
      • Direct use of the delete command
      • Direct use of a delete statement, but upon discovering that the object being deleted has child objects and the user requires Jimmer to handle these child objects, the delete statement is converted into a delete command
      • Using a save command, but Jimmer determines that the current object has discarded some associated objects, requiring dissociation operations for these no longer needed associated objects, and the corresponding dissociation operation is configured for deletion

      To delete an object, one must consider that it may have child objects, which need to be deleted first. However, child objects can have even deeper child objects, creating an infinite recursion problem.

      Although Jimmer handles the deleted object tree according to a fixed depth(set through the global configuration `jimmer.max-mutation-join-depth`, default is 2),this fixed depth is not infinite, when the object tree might have a greater depth, select statements must be used to recursively delete the object tree.

    • TUPLE_IS_UNSUPPORTED

      public static final QueryReason TUPLE_IS_UNSUPPORTED
      Sometimes, Jimmer requires multi-column in expression, i.e.,
      
       where (C1, C2, ...Cn) in (
           (V11, V12, ... V1n),
           (V21, V22, ... V2n),
           ...
           (Vm1, Vm2, ... Vmn)
       
      However, the current database does not support multi-column in, for example: org.babyfish.jimmer.sql.dialect.SqlServerDialect
    • TARGET_NOT_TRANSFERABLE

      public static final QueryReason TARGET_NOT_TRANSFERABLE
      If the associated property is OneToMany association or an inverse OneToOne (Inverse means mappedBy is specified, eg: @OneToOne(mappedBy="...")) association, then the associated objects are child objects of the current object.

      This cascading save behavior poses a business-level risk: assuming some child objects may already belong to other parent objects, the save command would snatch them away, making them become child objects of the current entity.

      By default, Jimmer adopts a very conservative approach, executing a select query to ensure this child object contention does not occur.

      If you believe this is not an issue and do not want to execute additional select queries for this purpose, you can disable this behavior. There are two ways to do this:

      1. Configuration at the current save command level:
        
             sqlClient.saveCommand(entity)
                  .setTargetTransferMode(
                      TreeNodeProps.CHILD_NODES,
                      TargetTransferMode.ALLOWED
                  )
             
        or
        
             sqlClient.saveCommand(entity)
                  .setTargetTransferModeAll(
                      TargetTransferMode.ALLOWED
                  )
             
      2. Global configuration:
        • Not using jimmer spring starter:
          
                   JSqlClient sqlClient = JSqlClient
                        .newBuilder()
                        .setTargetTransferable(true)
                        .build()
                   
        • Using jimmer spring starter: Set the global configuration `jimmer.target-transferable` to true

      Note: If both the current save command level configuration and the global configuration exist simultaneously, the former takes precedence.

    • UPSERT_NOT_SUPPORTED

      public static final QueryReason UPSERT_NOT_SUPPORTED
      The current database does not support upsert operations, or its upsert operation has not been integrated with Jimmer
    • OPTIMISTIC_LOCK

      public static final QueryReason OPTIMISTIC_LOCK
      The current database does not support mixing optimistic locking checks in upsert operations (so far, among the dialects implemented in Jimmer, only Postgres supports this)
    • KEY_UNIQUE_CONSTRAINT_REQUIRED

      public static final QueryReason KEY_UNIQUE_CONSTRAINT_REQUIRED
      The current entity type being operated on is annotated with KeyUniqueConstraint.

      Note that you shouldn't simply add this annotation just to eliminate this query behavior. This annotation represents the developer's promise to Jimmer that corresponding unique constraints or unique indexes exist in the data.

      Taking unique constraints as an example

      
       alter table your_table
           add constraint uq_your_constraint
               unique(
                   K1, K2, ... Kn,
                   LD
               );
       
      Where K1, K2, ... KN represent the column set corresponding to the entity's Key columns; LD represents the field corresponding to the LogicalDeleted column.

      If the entity supports logical deletion, it's recommended to use a method that can well distinguish different versions of data without introducing nullable long type values. For example

      
       @LogicalDeleted
       long deletedMillis();
       

      Note that middle tables specified by JoinTable don't have this configuration, but they definitely need to establish primary keys based on all columns (two required foreign keys, one optional logical deletion column, one optional type discrimination column).

    • NO_MORE_UNIQUE_CONSTRAINTS_REQUIRED

      public static final QueryReason NO_MORE_UNIQUE_CONSTRAINTS_REQUIRED
      The current database is MySQL, if there save object does not have Id property, Jimmer uses an insert ... on duplicate update... statement based on key properties, for example
      
       insert into your_table(NAME, EDITION, A, B, C)
       values('X', 1, 'a', 'b', 'c')
       on duplicate update
       ID = last_inserted_id(ID),
       A = VALUES(A), B = VALUES(B), C = VALUES(C)
       

      When the inserted columns do not include the primary key, MySQL will make judgments based on all non-primary key unique constraint fields, which may be far more than the definition of Key properties. and LogicalDeleted property

      If you want to eliminate queries, please configure KeyUniqueConstraint.noMoreUniqueConstraints() as true, promising that there are no other uniqueness constraints based on columns other than those defined by Key properties and LogicalDeleted in the database.

    • NULL_NOT_DISTINCT_REQUIRED

      public static final QueryReason NULL_NOT_DISTINCT_REQUIRED
      When saving objects without id properties, Jimmer will make the upsert statement determine whether existing data exists in the database based on Key properties and LogicalDeleted property.

      However, unlike id properties, key properties can be null. In relational databases, null is not equal to anything, including itself, which breaks uniqueness constraints. So, when a key of the current data is null, it will have to execute a select statement containing is null conditions to make a judgment.

      Fortunately, some databases can configure the behavior of null values in unique constraints, such as "Nulls not distinct" of Postgres

      If you have already set the uniqueness constraint based on Key properties and LogicalDeleted property in the database to nulls not distinct, you can set KeyUniqueConstraint.isNullNotDistinct() to true to resolve this issue.
    • IDENTITY_GENERATOR_REQUIRED

      public static final QueryReason IDENTITY_GENERATOR_REQUIRED
      Attempting to save an object without Id property, but the corresponding entity has not been configured with identity generation strategy.

      If the Id type is integer, consider enabling identity increment in the database and modifying the entity code as follows:

      
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       long id();
       
    • CANNOT_DELETE_DIRECTLY

      public static final QueryReason CANNOT_DELETE_DIRECTLY
      Direct use of a delete statement, but upon discovering that the object being deleted has child objects and the user requires Jimmer to handle these child objects, the delete statement is converted into a delete command
    • GET_ID_WHEN_UPDATE_NOTHING

      public static final QueryReason GET_ID_WHEN_UPDATE_NOTHING
      When explicitly updating objects based on Key properties, the objects being saved do not have any other properties that need to be modified. Simply querying the id data to populate the return result is sufficient.

      No handling is required for this situation.

    • GET_ID_FOR_KEY_BASE_UPDATE

      public static final QueryReason GET_ID_FOR_KEY_BASE_UPDATE
      When explicitly modifying objects based on Key properties, the underlying database lacks the ability to return the ids of existing objects, or this capability has not yet been integrated into Jimmer.
  • 方法详细资料

    • values

      public static QueryReason[] values()
      返回包含该枚举类的常量的数组, 顺序与声明这些常量的顺序相同
      返回:
      包含该枚举类的常量的数组,顺序与声明这些常量的顺序相同
    • valueOf

      public static QueryReason valueOf(String name)
      返回带有指定名称的该类的枚举常量。 字符串必须与用于声明该类的枚举常量的 标识符完全匹配。(不允许有多余 的空格字符。)
      参数:
      name - 要返回的枚举常量的名称。
      返回:
      返回带有指定名称的枚举常量
      抛出:
      IllegalArgumentException - 如果该枚举类没有带有指定名称的常量
      NullPointerException - 如果参数为空值