SPR-6717: Added support for database destroy scripts
This commit is contained in:
@@ -59,11 +59,12 @@ public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefiniti
|
||||
private void setDatabasePopulator(Element element, ParserContext context, BeanDefinitionBuilder builder) {
|
||||
List<Element> scripts = DomUtils.getChildElementsByTagName(element, "script");
|
||||
if (scripts.size() > 0) {
|
||||
builder.addPropertyValue("databasePopulator", createDatabasePopulator(element, scripts, context));
|
||||
builder.addPropertyValue("databasePopulator", createDatabasePopulator(element, scripts, context, "INIT"));
|
||||
builder.addPropertyValue("databaseCleaner", createDatabasePopulator(element, scripts, context, "DESTROY"));
|
||||
}
|
||||
}
|
||||
|
||||
private BeanDefinition createDatabasePopulator(Element element, List<Element> scripts, ParserContext context) {
|
||||
private BeanDefinition createDatabasePopulator(Element element, List<Element> scripts, ParserContext context, String execution) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CompositeDatabasePopulator.class);
|
||||
|
||||
boolean ignoreFailedDrops = element.getAttribute("ignore-failures").equals("DROPS");
|
||||
@@ -72,6 +73,14 @@ public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefiniti
|
||||
ManagedList<BeanMetadataElement> delegates = new ManagedList<BeanMetadataElement>();
|
||||
|
||||
for (Element scriptElement : scripts) {
|
||||
|
||||
String executionAttr = scriptElement.getAttribute("execution");
|
||||
if (!StringUtils.hasText(executionAttr)) {
|
||||
executionAttr = "INIT";
|
||||
}
|
||||
if (!execution.equals(executionAttr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder delegate = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class);
|
||||
delegate.addPropertyValue("ignoreFailedDrops", ignoreFailedDrops);
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -31,14 +32,15 @@ import org.springframework.util.Assert;
|
||||
* @since 3.0
|
||||
* @see DatabasePopulator
|
||||
*/
|
||||
public class DataSourceInitializer implements InitializingBean {
|
||||
public class DataSourceInitializer implements InitializingBean, DisposableBean {
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
private DatabasePopulator databasePopulator;
|
||||
|
||||
private boolean enabled = true;
|
||||
private DatabasePopulator databaseCleaner;
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* The {@link DataSource} to populate when this component is initialized.
|
||||
@@ -58,6 +60,16 @@ public class DataSourceInitializer implements InitializingBean {
|
||||
this.databasePopulator = databasePopulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a script execution to be run in the bean destruction callback, cleaning up the database and leaving it in
|
||||
* a known state for others.
|
||||
*
|
||||
* @param databaseCleaner the database script executor to run on destroy
|
||||
*/
|
||||
public void setDatabaseCleaner(DatabasePopulator databaseCleaner) {
|
||||
this.databaseCleaner = databaseCleaner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to explicitly enable or disable the database populator.
|
||||
* @param enabled true if the database populator will be called on startup
|
||||
@@ -66,30 +78,41 @@ public class DataSourceInitializer implements InitializingBean {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use the populator to set up data in the data source.
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (this.databasePopulator != null) {
|
||||
execute(this.databasePopulator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the populator to clean up data in the data source.
|
||||
*/
|
||||
public void destroy() throws Exception {
|
||||
if (this.databaseCleaner != null) {
|
||||
execute(this.databaseCleaner);
|
||||
}
|
||||
}
|
||||
|
||||
private void execute(DatabasePopulator populator) throws Exception {
|
||||
if (this.enabled) {
|
||||
Assert.state(this.dataSource != null, "DataSource must be provided");
|
||||
Assert.state(this.databasePopulator != null, "DatabasePopulator must be provided");
|
||||
Assert.state(populator != null, "DatabasePopulator must be provided");
|
||||
try {
|
||||
Connection connection = this.dataSource.getConnection();
|
||||
try {
|
||||
this.databasePopulator.populate(connection);
|
||||
}
|
||||
finally {
|
||||
populator.populate(connection);
|
||||
} finally {
|
||||
try {
|
||||
connection.close();
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
} catch (SQLException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new DataAccessResourceFailureException("Failed to populate database", ex);
|
||||
} catch (Exception ex) {
|
||||
throw new DataAccessResourceFailureException("Failed to execute database script", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
targetNamespace="http://www.springframework.org/schema/jdbc"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans"
|
||||
schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool"
|
||||
schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd" />
|
||||
|
||||
<xsd:element name="embedded-database">
|
||||
<xsd:annotation>
|
||||
@@ -80,8 +82,10 @@
|
||||
default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Is this bean "enabled", meaning the scripts will be executed?
|
||||
Defaults to true, but can be used to switch on and off the initialization depending on the environment.
|
||||
Is this bean "enabled", meaning the scripts will
|
||||
be executed?
|
||||
Defaults to true, but can be used to switch on and off
|
||||
the initialization depending on the environment.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -89,7 +93,8 @@
|
||||
default="NONE">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Should failed SQL statements be ignored during initialization?
|
||||
Should failed SQL statements be ignored during
|
||||
initialization?
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
@@ -136,6 +141,19 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="execution">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Indicate the timing of the execution of this script. Use INIT to execute on startup (as a bean initialization) and DESTROY to execute on shutdown (as a bean destruction callback).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="INIT" />
|
||||
<xsd:enumeration value="DESTROY" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="databaseType">
|
||||
|
||||
Reference in New Issue
Block a user