Prior to this commit, EmbeddedDatabaseFactory logged the name of an
embedded database just before it was created; however, the name alone
is not sufficient for connecting to the database via external tools
such as the H2 Web Console.
This commit updates EmbeddedDatabaseFactory to make it easier to
connect to embedded databases via external tools by logging the
complete connection URL for an embedded database as it's being created.
In addition, EmbeddedDatabaseFactory now logs when an embedded database
is being shut down.
Issue: SPR-13370
Some databases such as Oracle permit double quoted column aliases that
contain case-sensitive characters, single quotes, and other special
characters; however, prior to this commit, SqlScripts interpreted a
single quote nested within double quotes as the start of a string
literal resulting in improper parsing.
This commit addresses this issue by ensuring that double quoted strings
such as column aliases are properly parsed even when containing single
quotes.
Issue: SPR-13218
This commit improves the documentation for ScriptUtils by explicitly
mentioning that a JDBC Connection supplied to the one of the
executeSqlScript() methods will not be released automatically.
Issue: SPR-12908
Development teams often encounter errors with embedded databases if
their test suite inadvertently attempts to recreate additional
instances of the same database. This can happen quite easily if an XML
configuration file or @Configuration class is responsible for creating
an embedded database and the corresponding configuration is then reused
across multiple testing scenarios within the same test suite (i.e.,
within the same JVM process) -- for example, integration tests against
embedded databases whose ApplicationContext configuration only differs
with regard to which bean definition profiles are active.
The root cause of such errors is the fact that Spring's
EmbeddedDatabaseFactory (used internally by both the
<jdbc:embedded-database> XML namespace element and the
EmbeddedDatabaseBuilder for Java Config) will set the name of the
embedded database to "testdb" if not otherwise specified. For the case
of <jdbc:embedded-database>, the embedded database is typically
assigned a name equal to the bean's id. Thus, subsequent attempts to
create an embedded database will not result in a new database. Instead,
the same JDBC connection URL will be reused, and attempts to create a
new embedded database will actually point to an existing embedded
database created from the same configuration.
This commit addresses this common issue by introducing support for
generating unique names for embedded databases. This support can be
enabled via:
- EmbeddedDatabaseFactory.setGenerateUniqueDatabaseName()
- EmbeddedDatabaseBuilder.generateUniqueName()
- <jdbc:embedded-database generate-name="true" ... >
Issue: SPR-8849
Prior to this commit, the EmbeddedDatabaseBeanDefinitionParser set the
name of the embedded database that it configured to the value of its
'id'. This made it impossible to assign unique names to embedded
databases if the same bean 'id' (e.g, 'dataSource') was used across
multiple application contexts loaded within the same JVM, which is
often the case within an integration test suite. In contrast, the
EmbeddedDatabaseBuilder already provides support for setting the name
in Java Config. Thus there is a disconnect between XML and Java
configuration.
This commit addresses this issue by introducing a 'database-name'
attribute in <jdbc:embedded-database />. This allows developers to set
unique names for embedded databases -- for example, via a SpEL
expression or a property placeholder that is influenced by the current
active bean definition profiles.
Issue: SPR-12835
This commit modifies EmbeddedDatabaseBeanDefinitionParser so that the
<jdbc:embedded-database> XML namespace element can be declared as an
anonymous bean (i.e., without an explicit ID).
Issue: SPR-12834
This commit introduces spring-jdbc-4.2.xsd in order to support upcoming
changes to the JDBC XML namespace.
In addition, this commit polishes the XSD documentation with regard to
use cases for script execution.
To eliminate code duplication, ScriptStatementFailedException and
ScriptUtils now delegate to a new buildErrorMessage() utility method.
Issue: SPR-12752
Prior to this commit, it was possible to execute SQL scripts
programmatically via ResourceDatabasePopulator, JdbcTestUtils, and
ScriptUtils. Furthermore, it was also possible to execute SQL scripts
declaratively via the <jdbc> XML namespace. However, it was not
possible to execute SQL scripts declaratively on a per test class or
per test method basis.
This commit makes it possible to declaratively configure SQL scripts
for execution in integration tests via annotations that can be declared
at the class or method level. Details follow.
- Introduced a repeatable @DatabaseInitializer annotation that can be
used to configure SQL scripts at the class or method level with
method-level overrides. @DatabaseInitializers serves as a container
for @DatabaseInitializer.
- Introduced a new DatabaseInitializerTestExecutionListener that is
responsible for parsing @DatabaseInitializer and
@DatabaseInitializers and executing SQL scripts.
- DatabaseInitializerTestExecutionListener is registered by default in
abstract base test classes as well as in TestContextBootstrapper
implementations.
- @DatabaseInitializer and @DatabaseInitializers may be used as
meta-annotations; however, attribute overrides are not currently
supported for repeatable annotations used as meta-annotations. This
is a known limitation of Spring's AnnotationUtils.
- The semantics for locating SQL script resources is consistent with
@ContextConfiguration's semantics for locating XML configuration
files. In addition, a default SQL script can be detected based
either on the name of the annotated class or on the name of the
annotated test method.
- @DatabaseInitializer allows for specifying which DataSource and
PlatformTransactionManager to use from the test's
ApplicationContext, including default conventions consistent with
TransactionalTestExecutionListener and @TransactionConfiguration.
- @DatabaseInitializer supports all of the script configuration options
currently supported by ResourceDatabasePopulator.
- @DatabaseInitializer and DatabaseInitializerTestExecutionListener
support execution phases for scripts that dictate when SQL scripts
are executed (i.e., before or after a test method).
- SQL scripts can be executed within the current test's transaction if
present, outside of the current test's transaction if present, or
always in a new transaction, depending on the value of the boolean
requireNewTransaction flag in @DatabaseInitializer.
- DatabaseInitializerTestExecutionListener delegates to
ResourceDatabasePopulator#execute to actually execute the scripts.
Issue: SPR-7655
This commit adds a SQLErrorCodes instance for SAP DB, based on a
contribution from Andrew Clemons
Mostly based on SAP Hana SPS 07 with a few additional codes that are
only present is previous versions:
* -813 - Cannot connect to host somehost:30115 [Connection refused]
* -709 - Unknown host somehost:30115 [somehost], -709.]
* -708 - Cannot connect to jdbc:sap://somehost:30115 [Receive of connect failed.]
* -11210 - Invalid column index XYZ.
Issue: SPR-11770
Animal sniffer provides tools to assist verifying that classes
compiled with a newer JDK are compatible with an older JDK.
This integratesthe latest version of the tool (1.11) that
permits the use of custom annotations. Added @UsesJava7,
@UsesJava8 and @UsesSunHttpServer and annotated the few places
where we rely on a specific environment.
The verification process can be invoked by running the 'sniff'
task.
Issue: SPR-11604
polishing
Clean up compiler warnings in the tests of spring-jdbc. This commit
adds type parameters to all the types (mostly `List` and `Map`). In
addition it uses Java 5 autoboxing to get rid of all of the following
* new Integer
* new Long
* new Float
* new Double
* new Boolean
* new String
This should be unnoticeably faster since interning can be uses for
Integer and such.
After this commit the only warnings in spring-jdbc left are:
* raw type warning in `MapDataSourceLookupTests`, that code would never
compile with generics
* deprecation warning for `#queryForInt` and `#queryForLong`
Prior to this commit it was impossible to add additional scripts to a
ResourceDatabasePopulator after setScripts() had been invoked.
This commit fixes this by ensuring that the internal scripts list
continues to be modifiable when setScripts() is invoked.
Issue: SPR-11691
Prior to this commit ResourceDatabasePopulator did not assert any
preconditions for constructor and method arguments. Consequently,
errors would not be encountered until the populator was executed.
This commit addresses this issue by ensuring that preconditions for
constructor and method arguments are asserted immediately, throwing
IllegalArgumentExceptions where appropriate.
Issue: SPR-11690
Changed the value of ScriptUtils.EOF_STATEMENT_SEPARATOR from
"<<< END OF SCRIPT >>>" to "^^^ END OF SCRIPT ^^^" so that the angle
brackets do not have to be escaped in XML configuration files.
Issue: SPR-11687
Prior to Spring Framework 4.0.3, it was possible to supply a bogus
statement separator (i.e., a separator string that does not exist in
the configured SQL scripts) to ResourceDatabasePopulator with the side
effect that the entire contents of a script file would be interpreted
as a single SQL statement.
This undocumented feature was never intentional; however, some
developers came to rely on it. Unfortunately, changes made in
conjunction with SPR-9531 and SPR-11560 caused such scenarios to no
longer work.
This commit introduces first-class support for executing scripts which
contain a single statement that spans multiple lines but is not
followed by an explicit statement separator.
Specifically, ScriptUtils.EOF_STATEMENT_SEPARATOR may now be specified
as a 'virtual' statement separator to denote that a script contains a
single statement and no actual separator.
Issue: SPR-11687
To simplify common use cases, this commit introduces a new
execute(DataSource) method in ResourceDatabasePopulator that complements
the existing populate(Connection) method.
Issue: SPR-11629
Prior to this commit, the codebase was using a mix of log4j.xml
and log4j.properties for test-related logging configuration. This
can be an issue as log4j takes the xml variant first when looking
for a default bootstrap configuration.
In practice, some modules declaring the properties variant were
taking the xml variant configuration from another module.
The general structure of the configuration has also been
harmonized to provide a standard console output as well as an
easy way to enable trace logs for the current module.
This commit sets the DB_CLOSE_ON_EXIT flag to false for embedded H2
databases loaded using H2EmbeddedDatabaseConfigurer (i.e., via Spring's
<jdbc:embedded-database /> XML namespace, EmbeddedDatabaseBuilder,
EmbeddedDatabaseFactory, and EmbeddedDatabaseFactoryBean).
Issue: SPR-11573
This commit improves the configurability of EmbeddedDatabaseBuilder by
exposing the following new configuration methods.
- setDataSourceFactory(DataSourceFactory)
- addScripts(String...)
- setScriptEncoding(String)
- setSeparator(String)
- setCommentPrefix(String)
- setBlockCommentStartDelimiter(String)
- setBlockCommentEndDelimiter(String)
- continueOnError(boolean)
- ignoreFailedDrops(boolean)
If more fine grained control over the configuration of the embedded
database is required, users are recommended to use
EmbeddedDatabaseFactory with a ResourceDatabasePopulator and forego use
of the builder.
Issue: SPR-11410
In ScriptUtils and related classes, SQLExceptions are now caught and
wrapped in ScriptExceptions wherever feasible.
Affected "throws" declarations have also been revised as appropriate.
Issue: SPR-11564
This commit continues the work began in SPR-9531 as follows.
- ScriptException now extends DataAccessException.
- DatabasePopulator.populate() now explicitly throws ScriptException.
- Introduced UncategorizedScriptException.
- DatabasePopulatorUtils.execute() now throws an
UncategorizedScriptException instead of a
DataAccessResourceFailureException.
Issue: SPR-11564
Changes made in conjunction with SPR-9531, introduced a regression with
regard to support for using a single newline character as the statement
separator within SQL scripts. Investigation of the cause of this issue
resulted in the discovery of another, similar issue: support for
multiple newlines as a statement separator has been broken for years
but has gone unnoticed until now.
The reason that both of these issues have gone unnoticed is a result of
the fact that the test suite only executes SQL script integration tests
against HSQL DB, and HSQL does not care if two statements occur on the
same line; whereas, the H2 database will throw an exception if multiple
statements are included on the same line when executing an update.
This commit addresses both of these issues and provides further
enhancements to Spring's SQL script support as follows.
- ScriptUtils now properly checks if the supplied script contains the
custom statement separator or default separator before falling back
to the 'fallback' separator (i.e., newline).
- Introduced FALLBACK_STATEMENT_SEPARATOR constant in ScriptUtils.
- ScriptUtils.readScript() no longer omits empty lines from the input
file since a statement separator string may in fact be composed of
multiple newline characters.
- Introduced overloaded variants of splitSqlScript() and
executeSqlScript() in ScriptUtils with smaller argument lists for
common use cases.
- Extracted AbstractDatabasePopulatorTests from DatabasePopulatorTests
and introduced concrete HsqlDatabasePopulatorTests and
H2DatabasePopulatorTests subclasses for testing against HSQL and H2.
- Split ScriptUtilsTests into ScriptUtilsUnitTests and
ScriptUtilsIntegrationTests for faster builds.
Issue: SPR-11560