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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user