org.springframework.test.context.jdbc.SqlConfig Maven / Gradle / Ivy
Show all versions of spring-test Show documentation
/*
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.context.jdbc;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* {@code @SqlConfig} defines metadata that is used to determine how to parse
* and execute SQL scripts configured via the {@link Sql @Sql} annotation.
*
* Configuration Scope
* When declared as a class-level annotation on an integration test class,
* {@code @SqlConfig} serves as global configuration
* for all SQL scripts within the test class hierarchy. When declared directly
* via the {@link Sql#config config} attribute of the {@code @Sql} annotation,
* {@code @SqlConfig} serves as local configuration
* for the SQL scripts declared within the enclosing {@code @Sql} annotation.
*
*
Default Values
* Every attribute in {@code @SqlConfig} has an implicit default value
* which is documented in the javadocs of the corresponding attribute. Due to the
* rules defined for annotation attributes in the Java Language Specification, it
* is unfortunately not possible to assign a value of {@code null} to an annotation
* attribute. Thus, in order to support overrides of inherited global
* configuration, {@code @SqlConfig} attributes have an explicit
* {@code default} value of either {@code ""} for Strings, {}
for
* arrays, or {@code DEFAULT} for Enums. This approach allows local declarations
* of {@code @SqlConfig} to selectively override individual attributes from global
* declarations of {@code @SqlConfig} by providing a value other than {@code ""},
* {}
, or {@code DEFAULT}.
*
*
Inheritance and Overrides
* Global {@code @SqlConfig} attributes are inherited whenever local
* {@code @SqlConfig} attributes do not supply an explicit value other than
* {@code ""}, {}
, or {@code DEFAULT}. Explicit local configuration
* therefore overrides global configuration.
*
*
As of Spring Framework 5.3, this annotation will be inherited from an
* enclosing test class by default. See
* {@link org.springframework.test.context.NestedTestConfiguration @NestedTestConfiguration}
* for details.
*
* @author Sam Brannen
* @author Tadaya Tsuyukubo
* @since 4.1
* @see Sql
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface SqlConfig {
/**
* The bean name of the {@link javax.sql.DataSource} against which the
* scripts should be executed.
*
The name is only required if there is more than one bean of type
* {@code DataSource} in the test's {@code ApplicationContext}. If there
* is only one such bean, it is not necessary to specify a bean name.
*
Defaults to an empty string, requiring that one of the following is
* true:
*
* - An explicit bean name is defined in a global declaration of
* {@code @SqlConfig}.
*
- The data source can be retrieved from the transaction manager
* by using reflection to invoke a public method named
* {@code getDataSource()} on the transaction manager.
*
- There is only one bean of type {@code DataSource} in the test's
* {@code ApplicationContext}.
* - The {@code DataSource} to use is named {@code "dataSource"}.
*
* @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveDataSource
*/
String dataSource() default "";
/**
* The bean name of the {@link org.springframework.transaction.PlatformTransactionManager
* PlatformTransactionManager} that should be used to drive transactions.
* The name is only used if there is more than one bean of type
* {@code PlatformTransactionManager} in the test's {@code ApplicationContext}.
* If there is only one such bean, it is not necessary to specify a bean name.
*
Defaults to an empty string, requiring that one of the following is
* true:
*
* - An explicit bean name is defined in a global declaration of
* {@code @SqlConfig}.
*
- There is only one bean of type {@code PlatformTransactionManager} in
* the test's {@code ApplicationContext}.
* - {@link org.springframework.transaction.annotation.TransactionManagementConfigurer
* TransactionManagementConfigurer} has been implemented to specify which
* {@code PlatformTransactionManager} bean should be used for annotation-driven
* transaction management.
* - The {@code PlatformTransactionManager} to use is named
* {@code "transactionManager"}.
*
* @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveTransactionManager
*/
String transactionManager() default "";
/**
* The mode to use when determining whether SQL scripts should be
* executed within a transaction.
* Defaults to {@link TransactionMode#DEFAULT DEFAULT}.
*
Can be set to {@link TransactionMode#ISOLATED} to ensure that the SQL
* scripts are executed in a new, isolated transaction that will be immediately
* committed.
* @see TransactionMode
*/
TransactionMode transactionMode() default TransactionMode.DEFAULT;
/**
* The encoding for the supplied SQL scripts, if different from the platform
* encoding.
*
An empty string denotes that the platform encoding should be used.
*/
String encoding() default "";
/**
* The character string used to separate individual statements within the
* SQL scripts.
*
Implicitly defaults to {@code ";"} if not specified and falls back to
* {@code "\n"} as a last resort.
*
May be set to
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#EOF_STATEMENT_SEPARATOR}
* to signal that each script contains a single statement without a
* separator.
* @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_STATEMENT_SEPARATOR
* @see org.springframework.jdbc.datasource.init.ScriptUtils#EOF_STATEMENT_SEPARATOR
*/
String separator() default "";
/**
* The prefix that identifies single-line comments within the SQL scripts.
*
Implicitly defaults to {@code "--"}.
*
This attribute may not be used in conjunction with
* {@link #commentPrefixes commentPrefixes}, but it may be used instead of
* {@link #commentPrefixes commentPrefixes}.
* @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_COMMENT_PREFIX
* @see #commentPrefixes
*/
String commentPrefix() default "";
/**
* The prefixes that identify single-line comments within the SQL scripts.
*
Implicitly defaults to {@code ["--"]}.
*
This attribute may not be used in conjunction with
* {@link #commentPrefix commentPrefix}, but it may be used instead of
* {@link #commentPrefix commentPrefix}.
* @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_COMMENT_PREFIXES
* @see #commentPrefix
* @since 5.2
*/
String[] commentPrefixes() default {};
/**
* The start delimiter that identifies block comments within the SQL scripts.
*
Implicitly defaults to {@code "/*"}.
* @see #blockCommentEndDelimiter
* @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_BLOCK_COMMENT_START_DELIMITER
*/
String blockCommentStartDelimiter() default "";
/**
* The end delimiter that identifies block comments within the SQL scripts.
*
Implicitly defaults to "*/"
.
* @see #blockCommentStartDelimiter
* @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_BLOCK_COMMENT_END_DELIMITER
*/
String blockCommentEndDelimiter() default "";
/**
* The mode to use when an error is encountered while executing an
* SQL statement.
*
Defaults to {@link ErrorMode#DEFAULT DEFAULT}.
* @see ErrorMode
*/
ErrorMode errorMode() default ErrorMode.DEFAULT;
/**
* Enumeration of modes that dictate whether SQL scripts should be
* executed within a transaction and what the transaction propagation behavior
* should be.
*/
enum TransactionMode {
/**
* Indicates that the default transaction mode should be used.
*
The meaning of default depends on the context in which
* {@code @SqlConfig} is declared:
*
* - If {@code @SqlConfig} is declared only locally,
* the default transaction mode is {@link #INFERRED}.
* - If {@code @SqlConfig} is declared globally, the default transaction
* mode is {@link #INFERRED}.
* - If {@code @SqlConfig} is declared globally and
* locally, the default transaction mode for the local declaration is
* inherited from the global declaration.
*
*/
DEFAULT,
/**
* Indicates that the transaction mode to use when executing SQL
* scripts should be inferred using the rules listed below.
* In the context of these rules, the term "available"
* means that the bean for the data source or transaction manager
* is either explicitly specified via a corresponding annotation
* attribute in {@code @SqlConfig} or discoverable via conventions. See
* {@link org.springframework.test.context.transaction.TestContextTransactionUtils TestContextTransactionUtils}
* for details on the conventions used to discover such beans in
* the {@code ApplicationContext}.
*
* Inference Rules
*
* - If neither a transaction manager nor a data source is
* available, an exception will be thrown.
*
- If a transaction manager is not available but a data source
* is available, SQL scripts will be executed directly against the
* data source without a transaction.
*
- If a transaction manager is available:
*
* - If a data source is not available, an attempt will be made
* to retrieve it from the transaction manager by using reflection
* to invoke a public method named {@code getDataSource()} on the
* transaction manager. If the attempt fails, an exception will be
* thrown.
*
- Using the resolved transaction manager and data source, SQL
* scripts will be executed within an existing transaction if
* present; otherwise, scripts will be executed in a new transaction
* that will be immediately committed. An existing
* transaction will typically be managed by the
* {@link org.springframework.test.context.transaction.TransactionalTestExecutionListener TransactionalTestExecutionListener}.
*
*
* @see #ISOLATED
* @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveDataSource
* @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveTransactionManager
*/
INFERRED,
/**
* Indicates that SQL scripts should always be executed in a new,
* isolated transaction that will be immediately committed.
* In contrast to {@link #INFERRED}, this mode requires the
* presence of a transaction manager and a data
* source.
*/
ISOLATED
}
/**
* Enumeration of modes that dictate how errors are handled while
* executing SQL statements.
*/
enum ErrorMode {
/**
* Indicates that the default error mode should be used.
*
The meaning of default depends on the context in which
* {@code @SqlConfig} is declared:
*
* - If {@code @SqlConfig} is declared only locally,
* the default error mode is {@link #FAIL_ON_ERROR}.
* - If {@code @SqlConfig} is declared globally, the default error
* mode is {@link #FAIL_ON_ERROR}.
* - If {@code @SqlConfig} is declared globally and
* locally, the default error mode for the local declaration is
* inherited from the global declaration.
*
*/
DEFAULT,
/**
* Indicates that script execution will fail if an error is encountered.
* In other words, no errors should be ignored.
* This is effectively the default error mode so that if a script
* is accidentally executed, it will fail fast if any SQL statement in
* the script results in an error.
* @see #CONTINUE_ON_ERROR
*/
FAIL_ON_ERROR,
/**
* Indicates that all errors in SQL scripts should be logged but not
* propagated as exceptions.
*
{@code CONTINUE_ON_ERROR} is the logical opposite of
* {@code FAIL_ON_ERROR} and a superset of {@code IGNORE_FAILED_DROPS}.
* @see #FAIL_ON_ERROR
* @see #IGNORE_FAILED_DROPS
*/
CONTINUE_ON_ERROR,
/**
* Indicates that failed SQL {@code DROP} statements can be ignored.
*
This is useful for a non-embedded database whose SQL dialect does
* not support an {@code IF EXISTS} clause in a {@code DROP} statement.
* @see #CONTINUE_ON_ERROR
*/
IGNORE_FAILED_DROPS
}
}