diff --git a/spring-framework-reference/src/jdbc.xml b/spring-framework-reference/src/jdbc.xml index c1209b254fd..44663cb3a77 100644 --- a/spring-framework-reference/src/jdbc.xml +++ b/spring-framework-reference/src/jdbc.xml @@ -2874,4 +2874,150 @@ public class DataAccessUnitTestTemplate { + +
+ Initializing a DataSource + + The org.springframework.jdbc.datasource.init + package provides support for initializing an existing + DataSource. The embedded database support provides + one option for creating and initializing a + DataSource for an application, but sometimes you + need to initialize an instance running on a server somewhere. + +
+ Initializing a database instance using Spring XML + + If you want to initialize a database and you can provide a + reference to a DataSource bean, use the + initialize-datasource tag in the + spring-jdbc namespace: + + <jdbc:initialize-database data-source="dataSource"> + <jdbc:script location="classpath:com/foo/sql/db-schema.sql"/> + <jdbc:script location="classpath:com/foo/sql/db-test-data.sql"/> +</jdbc:initialize-database> + + The example above runs the two scripts specified against the + database: the first script is a schema creation, and the second is a + test data set insert. The script locations can also be patterns with + wildcards in the usual ant style used for resources in Spring (e.g. + classpath*:/com/foo/**/sql/*-data.sql). If a pattern is + used the scripts are executed in lexical order of their URL or + filename. + + The default behaviour of the database initializer is to + unconditionally execute the scripts provided. This will not always be + what you want, for instance if running against an existing database that + already has test data in it. The likelihood of accidentally deleting + data is reduced by the commonest pattern (as shown above) that creates + the tables first and then inserts the data - the first step will fail if + the tables already exist. + + However, to get more control the creation and deletion of existing + data the XML namespace provides a couple more options. The first is flag + to switch the initialization on and off. This can be set according to + the environment (e.g. to pull a boolean value from system properties or + an environment bean), e.g.<jdbc:initialize-database data-source="dataSource" + enabled="#{systemProperties.INITIALIZE_DATABASE}"> + <jdbc:script location="..."/> +</jdbc:initialize-database> + + The second option to control what happens with existing data is to + be more tolerant of failures. To this end you can control the ability of + the initializer to ignore certain errors in the SQL it executes from the + scripts, e.g. + + <jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS"> + <jdbc:script location="..."/> +</jdbc:initialize-database>In this example we are + saying we expect that sometimes the scripts will be run against an empty + dtabase and there are some DROP statements in the scripts which would + therefore fail. So failed SQL DROP statements will be + ignored, but other failures will cause an exception. This is useful if + your SQL dialect doesn't support DROP ... IF EXISTS (or + similar) but you want to unconditionally remove all test data before + re-creating it. In that case the first script is usually a set of drops, + followed by a set of CREATE statements. + + The ignore-failures option can be set to + NONE (the default), DROPS (ignore failed + drops) or ALL (ignore all failures). + + If you need more control than you get from the XML namespace, you + can simply use the DataSourceInitializer + directly, and define it as a component in your application. + +
+ Initialization of Other Components that Depend on the + Database + + A large class of applications can just use the database + initializer with no further complications: those that do not use the + database until after the Spring context has started. If your + application is not one of those then you might + need to read the rest of this section. + + The database initializer depends on a data source instance and + runs the scripts provided in its initialization callback (c.f. + init-method in an XML bean definition or + InitializingBean). If other beans depend on the same data + source and also use the data source in an initialization callback then + there might be a problem because the data has not yet been + initialized. A common example of this is a cache that initializes + eagerly and loads up data from the database on application + startup. + + To get round this issue you two options: change your cache + initialization strategy to a later phase, or ensure that the database + initializer is initialized first. + + The first option might be easy if the application is in your + control, and not otherwise. Some suggestions for how to implement this + are + + Make the cache initialize lazily on first usage, which + improves application startup time + + + + Use a Spring ApplicationEvent or similar + custom observer mechanism to trigger the cache initialization. + ContextRefreshedEvent is always published by the + context when it is ready for use (after all beans have been + initialized), so that is often a useful hook. + + + + The second option can also be easy. Some suggestions on how to + implement this are + + Rely on Spring BeanFactory default behaviour, which is + that beans are initialized in registration order. You can easily + arrange that by adopting the common practice of a set of + <import/> elements that order your application modules, + and ensure that the database and database initialization are + listed first + + + + Separate the datasource and the business components that + use it and control their startup order by putting them in + separate ApplicationContext instances (e.g. parent has the + datasource and child has the business components). This + structure is common in Spring web applications, but can be more + generally applied. + + + + Use a modular runtime like SpringSource dm Server and + separate the data source and the components that depend on it. + E.g. specify the bundle start up order as datasource -> + initializer -> business components. + + +
+
+