Introduce database-name in <jdbc:embedded-database>
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 is contained in:
parent
7e2f12cf9f
commit
c36c6cbfaa
|
|
@ -43,10 +43,16 @@ import org.w3c.dom.Element;
|
|||
*/
|
||||
class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
/**
|
||||
* Constant for the "database-name" attribute.
|
||||
*/
|
||||
static final String DB_NAME_ATTRIBUTE = "database-name";
|
||||
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(EmbeddedDatabaseFactoryBean.class);
|
||||
useIdAsDatabaseNameIfGiven(element, builder);
|
||||
setDatabaseName(element, builder);
|
||||
setDatabaseType(element, builder);
|
||||
DatabasePopulatorConfigUtils.setDatabasePopulator(element, builder);
|
||||
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
|
||||
|
|
@ -58,11 +64,20 @@ class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser
|
|||
return true;
|
||||
}
|
||||
|
||||
private void useIdAsDatabaseNameIfGiven(Element element, BeanDefinitionBuilder builder) {
|
||||
String id = element.getAttribute(ID_ATTRIBUTE);
|
||||
if (StringUtils.hasText(id)) {
|
||||
builder.addPropertyValue("databaseName", id);
|
||||
private void setDatabaseName(Element element, BeanDefinitionBuilder builder) {
|
||||
// 1) Check for an explicit database name
|
||||
String name = element.getAttribute(DB_NAME_ATTRIBUTE);
|
||||
|
||||
// 2) Fall back to an implicit database name based on the ID
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = element.getAttribute(ID_ATTRIBUTE);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(name)) {
|
||||
builder.addPropertyValue("databaseName", name);
|
||||
}
|
||||
|
||||
// 3) Let EmbeddedDatabaseFactory set the default "testdb" name
|
||||
}
|
||||
|
||||
private void setDatabaseType(Element element, BeanDefinitionBuilder builder) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,16 @@
|
|||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="database-name" type="xsd:string" default="">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name to assign to the embedded database. Note that this is not the
|
||||
bean name but rather the name of the embedded database as used in the JDBC
|
||||
connection URL for the database. Defaults to "testdb" if an explicit bean
|
||||
'id' has not been provided.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="type" type="databaseType" default="HSQL">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean;
|
||||
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
||||
import org.springframework.tests.Assume;
|
||||
|
|
@ -38,6 +39,7 @@ import org.springframework.tests.TestGroup;
|
|||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory.*;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
|
|
@ -65,13 +67,24 @@ public class JdbcNamespaceIntegrationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void createWithAnonymousDataSource() throws Exception {
|
||||
assertCorrectSetupAndCloseContextForSingleDataSource("jdbc-config-anonymous-datasource.xml", 1);
|
||||
public void createWithResourcePattern() throws Exception {
|
||||
assertCorrectSetup("jdbc-config-pattern.xml", "dataSource");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWithResourcePattern() throws Exception {
|
||||
assertCorrectSetup("jdbc-config-pattern.xml", "dataSource");
|
||||
public void createWithAnonymousDataSourceAndDefaultDatabaseName() throws Exception {
|
||||
assertCorrectSetupForSingleDataSource("jdbc-config-db-name-default-and-anonymous-datasource.xml",
|
||||
DEFAULT_DATABASE_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWithImplicitDatabaseName() throws Exception {
|
||||
assertCorrectSetupForSingleDataSource("jdbc-config-db-name-implicit.xml", "dataSource");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWithExplicitDatabaseName() throws Exception {
|
||||
assertCorrectSetupForSingleDataSource("jdbc-config-db-name-explicit.xml", "customDbName");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -165,8 +178,10 @@ public class JdbcNamespaceIntegrationTests {
|
|||
try {
|
||||
for (String dataSourceName : dataSources) {
|
||||
DataSource dataSource = context.getBean(dataSourceName, DataSource.class);
|
||||
JdbcTemplate template = new JdbcTemplate(dataSource);
|
||||
assertNumRowsInTestTable(template, count);
|
||||
assertNumRowsInTestTable(new JdbcTemplate(dataSource), count);
|
||||
assertTrue(dataSource instanceof AbstractDriverBasedDataSource);
|
||||
AbstractDriverBasedDataSource adbDataSource = (AbstractDriverBasedDataSource) dataSource;
|
||||
assertThat(adbDataSource.getUrl(), containsString(dataSourceName));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
|
@ -174,12 +189,14 @@ public class JdbcNamespaceIntegrationTests {
|
|||
}
|
||||
}
|
||||
|
||||
private void assertCorrectSetupAndCloseContextForSingleDataSource(String file, int count) {
|
||||
private void assertCorrectSetupForSingleDataSource(String file, String dbName) {
|
||||
ConfigurableApplicationContext context = context(file);
|
||||
try {
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
JdbcTemplate template = new JdbcTemplate(dataSource);
|
||||
assertNumRowsInTestTable(template, count);
|
||||
assertNumRowsInTestTable(new JdbcTemplate(dataSource), 1);
|
||||
assertTrue(dataSource instanceof AbstractDriverBasedDataSource);
|
||||
AbstractDriverBasedDataSource adbDataSource = (AbstractDriverBasedDataSource) dataSource;
|
||||
assertThat(adbDataSource.getUrl(), containsString(dbName));
|
||||
}
|
||||
finally {
|
||||
context.close();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns="http://www.springframework.org/schema/jdbc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd">
|
||||
|
||||
<embedded-database id="dataSource" database-name="customDbName">
|
||||
<script location="classpath:org/springframework/jdbc/config/db-schema.sql" />
|
||||
<script location="classpath:org/springframework/jdbc/config/db-test-data.sql" />
|
||||
</embedded-database>
|
||||
|
||||
</beans:beans>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns="http://www.springframework.org/schema/jdbc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd">
|
||||
|
||||
<embedded-database id="dataSource">
|
||||
<script location="classpath:org/springframework/jdbc/config/db-schema.sql" />
|
||||
<script location="classpath:org/springframework/jdbc/config/db-test-data.sql" />
|
||||
</embedded-database>
|
||||
|
||||
</beans:beans>
|
||||
Loading…
Reference in New Issue