001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.context.jdbc; 018 019import java.lang.annotation.Documented; 020import java.lang.annotation.ElementType; 021import java.lang.annotation.Inherited; 022import java.lang.annotation.Retention; 023import java.lang.annotation.RetentionPolicy; 024import java.lang.annotation.Target; 025 026/** 027 * {@code @SqlConfig} defines metadata that is used to determine how to parse 028 * and execute SQL scripts configured via the {@link Sql @Sql} annotation. 029 * 030 * <h3>Configuration Scope</h3> 031 * <p>When declared as a class-level annotation on an integration test class, 032 * {@code @SqlConfig} serves as <strong><em>global</em></strong> configuration 033 * for all SQL scripts within the test class hierarchy. When declared directly 034 * via the {@link Sql#config config} attribute of the {@code @Sql} annotation, 035 * {@code @SqlConfig} serves as <strong><em>local</em></strong> configuration 036 * for the SQL scripts declared within the enclosing {@code @Sql} annotation. 037 * 038 * <h3>Default Values</h3> 039 * <p>Every attribute in {@code @SqlConfig} has an <em>implicit</em> default value 040 * which is documented in the javadocs of the corresponding attribute. Due to the 041 * rules defined for annotation attributes in the Java Language Specification, it 042 * is unfortunately not possible to assign a value of {@code null} to an annotation 043 * attribute. Thus, in order to support overrides of <em>inherited</em> global 044 * configuration, {@code @SqlConfig} attributes have an <em>explicit</em> 045 * {@code default} value of either {@code ""} for Strings or {@code DEFAULT} for 046 * Enums. This approach allows local declarations of {@code @SqlConfig} to 047 * selectively override individual attributes from global declarations of 048 * {@code @SqlConfig} by providing a value other than {@code ""} or {@code DEFAULT}. 049 * 050 * <h3>Inheritance and Overrides</h3> 051 * <p>Global {@code @SqlConfig} attributes are <em>inherited</em> whenever local 052 * {@code @SqlConfig} attributes do not supply an explicit value other than 053 * {@code ""} or {@code DEFAULT}. Explicit local configuration therefore 054 * <em>overrides</em> global configuration. 055 * 056 * @author Sam Brannen 057 * @author Tadaya Tsuyukubo 058 * @since 4.1 059 * @see Sql 060 */ 061@Target(ElementType.TYPE) 062@Retention(RetentionPolicy.RUNTIME) 063@Documented 064@Inherited 065public @interface SqlConfig { 066 067 /** 068 * The bean name of the {@link javax.sql.DataSource} against which the 069 * scripts should be executed. 070 * <p>The name is only required if there is more than one bean of type 071 * {@code DataSource} in the test's {@code ApplicationContext}. If there 072 * is only one such bean, it is not necessary to specify a bean name. 073 * <p>Defaults to an empty string, requiring that one of the following is 074 * true: 075 * <ol> 076 * <li>An explicit bean name is defined in a global declaration of 077 * {@code @SqlConfig}. 078 * <li>The data source can be retrieved from the transaction manager 079 * by using reflection to invoke a public method named 080 * {@code getDataSource()} on the transaction manager. 081 * <li>There is only one bean of type {@code DataSource} in the test's 082 * {@code ApplicationContext}.</li> 083 * <li>The {@code DataSource} to use is named {@code "dataSource"}.</li> 084 * </ol> 085 * @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveDataSource 086 */ 087 String dataSource() default ""; 088 089 /** 090 * The bean name of the {@link org.springframework.transaction.PlatformTransactionManager 091 * PlatformTransactionManager} that should be used to drive transactions. 092 * <p>The name is only used if there is more than one bean of type 093 * {@code PlatformTransactionManager} in the test's {@code ApplicationContext}. 094 * If there is only one such bean, it is not necessary to specify a bean name. 095 * <p>Defaults to an empty string, requiring that one of the following is 096 * true: 097 * <ol> 098 * <li>An explicit bean name is defined in a global declaration of 099 * {@code @SqlConfig}. 100 * <li>There is only one bean of type {@code PlatformTransactionManager} in 101 * the test's {@code ApplicationContext}.</li> 102 * <li>{@link org.springframework.transaction.annotation.TransactionManagementConfigurer 103 * TransactionManagementConfigurer} has been implemented to specify which 104 * {@code PlatformTransactionManager} bean should be used for annotation-driven 105 * transaction management.</li> 106 * <li>The {@code PlatformTransactionManager} to use is named 107 * {@code "transactionManager"}.</li> 108 * </ol> 109 * @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveTransactionManager 110 */ 111 String transactionManager() default ""; 112 113 /** 114 * The <em>mode</em> to use when determining whether SQL scripts should be 115 * executed within a transaction. 116 * <p>Defaults to {@link TransactionMode#DEFAULT DEFAULT}. 117 * <p>Can be set to {@link TransactionMode#ISOLATED} to ensure that the SQL 118 * scripts are executed in a new, isolated transaction that will be immediately 119 * committed. 120 * @see TransactionMode 121 */ 122 TransactionMode transactionMode() default TransactionMode.DEFAULT; 123 124 /** 125 * The encoding for the supplied SQL scripts, if different from the platform 126 * encoding. 127 * <p>An empty string denotes that the platform encoding should be used. 128 */ 129 String encoding() default ""; 130 131 /** 132 * The character string used to separate individual statements within the 133 * SQL scripts. 134 * <p>Implicitly defaults to {@code ";"} if not specified and falls back to 135 * {@code "\n"} as a last resort. 136 * <p>May be set to 137 * {@link org.springframework.jdbc.datasource.init.ScriptUtils#EOF_STATEMENT_SEPARATOR} 138 * to signal that each script contains a single statement without a 139 * separator. 140 * @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_STATEMENT_SEPARATOR 141 * @see org.springframework.jdbc.datasource.init.ScriptUtils#EOF_STATEMENT_SEPARATOR 142 */ 143 String separator() default ""; 144 145 /** 146 * The prefix that identifies single-line comments within the SQL scripts. 147 * <p>Implicitly defaults to {@code "--"}. 148 * @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_COMMENT_PREFIX 149 */ 150 String commentPrefix() default ""; 151 152 /** 153 * The start delimiter that identifies block comments within the SQL scripts. 154 * <p>Implicitly defaults to {@code "/*"}. 155 * @see #blockCommentEndDelimiter 156 * @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_BLOCK_COMMENT_START_DELIMITER 157 */ 158 String blockCommentStartDelimiter() default ""; 159 160 /** 161 * The end delimiter that identifies block comments within the SQL scripts. 162 * <p>Implicitly defaults to <code>"*/"</code>. 163 * @see #blockCommentStartDelimiter 164 * @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_BLOCK_COMMENT_END_DELIMITER 165 */ 166 String blockCommentEndDelimiter() default ""; 167 168 /** 169 * The <em>mode</em> to use when an error is encountered while executing an 170 * SQL statement. 171 * <p>Defaults to {@link ErrorMode#DEFAULT DEFAULT}. 172 * @see ErrorMode 173 */ 174 ErrorMode errorMode() default ErrorMode.DEFAULT; 175 176 177 /** 178 * Enumeration of <em>modes</em> that dictate whether SQL scripts should be 179 * executed within a transaction and what the transaction propagation behavior 180 * should be. 181 */ 182 enum TransactionMode { 183 184 /** 185 * Indicates that the <em>default</em> transaction mode should be used. 186 * <p>The meaning of <em>default</em> depends on the context in which 187 * {@code @SqlConfig} is declared: 188 * <ul> 189 * <li>If {@code @SqlConfig} is declared <strong>only</strong> locally, 190 * the default transaction mode is {@link #INFERRED}.</li> 191 * <li>If {@code @SqlConfig} is declared globally, the default transaction 192 * mode is {@link #INFERRED}.</li> 193 * <li>If {@code @SqlConfig} is declared globally <strong>and</strong> 194 * locally, the default transaction mode for the local declaration is 195 * inherited from the global declaration.</li> 196 * </ul> 197 */ 198 DEFAULT, 199 200 /** 201 * Indicates that the transaction mode to use when executing SQL 202 * scripts should be <em>inferred</em> using the rules listed below. 203 * In the context of these rules, the term "<em>available</em>" 204 * means that the bean for the data source or transaction manager 205 * is either explicitly specified via a corresponding annotation 206 * attribute in {@code @SqlConfig} or discoverable via conventions. See 207 * {@link org.springframework.test.context.transaction.TestContextTransactionUtils TestContextTransactionUtils} 208 * for details on the conventions used to discover such beans in 209 * the {@code ApplicationContext}. 210 * 211 * <h4>Inference Rules</h4> 212 * <ol> 213 * <li>If neither a transaction manager nor a data source is 214 * available, an exception will be thrown. 215 * <li>If a transaction manager is not available but a data source 216 * is available, SQL scripts will be executed directly against the 217 * data source without a transaction. 218 * <li>If a transaction manager is available: 219 * <ul> 220 * <li>If a data source is not available, an attempt will be made 221 * to retrieve it from the transaction manager by using reflection 222 * to invoke a public method named {@code getDataSource()} on the 223 * transaction manager. If the attempt fails, an exception will be 224 * thrown. 225 * <li>Using the resolved transaction manager and data source, SQL 226 * scripts will be executed within an existing transaction if 227 * present; otherwise, scripts will be executed in a new transaction 228 * that will be immediately committed. An <em>existing</em> 229 * transaction will typically be managed by the 230 * {@link org.springframework.test.context.transaction.TransactionalTestExecutionListener TransactionalTestExecutionListener}. 231 * </ul> 232 * </ol> 233 * @see #ISOLATED 234 * @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveDataSource 235 * @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveTransactionManager 236 */ 237 INFERRED, 238 239 /** 240 * Indicates that SQL scripts should always be executed in a new, 241 * <em>isolated</em> transaction that will be immediately committed. 242 * <p>In contrast to {@link #INFERRED}, this mode requires the 243 * presence of a transaction manager <strong>and</strong> a data 244 * source. 245 */ 246 ISOLATED 247 } 248 249 250 /** 251 * Enumeration of <em>modes</em> that dictate how errors are handled while 252 * executing SQL statements. 253 */ 254 enum ErrorMode { 255 256 /** 257 * Indicates that the <em>default</em> error mode should be used. 258 * <p>The meaning of <em>default</em> depends on the context in which 259 * {@code @SqlConfig} is declared: 260 * <ul> 261 * <li>If {@code @SqlConfig} is declared <strong>only</strong> locally, 262 * the default error mode is {@link #FAIL_ON_ERROR}.</li> 263 * <li>If {@code @SqlConfig} is declared globally, the default error 264 * mode is {@link #FAIL_ON_ERROR}.</li> 265 * <li>If {@code @SqlConfig} is declared globally <strong>and</strong> 266 * locally, the default error mode for the local declaration is 267 * inherited from the global declaration.</li> 268 * </ul> 269 */ 270 DEFAULT, 271 272 /** 273 * Indicates that script execution will fail if an error is encountered. 274 * In other words, no errors should be ignored. 275 * <p>This is effectively the default error mode so that if a script 276 * is accidentally executed, it will fail fast if any SQL statement in 277 * the script results in an error. 278 * @see #CONTINUE_ON_ERROR 279 */ 280 FAIL_ON_ERROR, 281 282 /** 283 * Indicates that all errors in SQL scripts should be logged but not 284 * propagated as exceptions. 285 * <p>{@code CONTINUE_ON_ERROR} is the logical <em>opposite</em> of 286 * {@code FAIL_ON_ERROR} and a <em>superset</em> of {@code IGNORE_FAILED_DROPS}. 287 * @see #FAIL_ON_ERROR 288 * @see #IGNORE_FAILED_DROPS 289 */ 290 CONTINUE_ON_ERROR, 291 292 /** 293 * Indicates that failed SQL {@code DROP} statements can be ignored. 294 * <p>This is useful for a non-embedded database whose SQL dialect does 295 * not support an {@code IF EXISTS} clause in a {@code DROP} statement. 296 * @see #CONTINUE_ON_ERROR 297 */ 298 IGNORE_FAILED_DROPS 299 } 300 301}