Skip to content

Commit c36c6cb

Browse files
committed
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
1 parent 7e2f12c commit c36c6cb

File tree

6 files changed

+80
-14
lines changed

6 files changed

+80
-14
lines changed

Diff for: spring-jdbc/src/main/java/org/springframework/jdbc/config/EmbeddedDatabaseBeanDefinitionParser.java

+20-5
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,16 @@
4343
*/
4444
class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser {
4545

46+
/**
47+
* Constant for the "database-name" attribute.
48+
*/
49+
static final String DB_NAME_ATTRIBUTE = "database-name";
50+
51+
4652
@Override
4753
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
4854
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(EmbeddedDatabaseFactoryBean.class);
49-
useIdAsDatabaseNameIfGiven(element, builder);
55+
setDatabaseName(element, builder);
5056
setDatabaseType(element, builder);
5157
DatabasePopulatorConfigUtils.setDatabasePopulator(element, builder);
5258
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
@@ -58,11 +64,20 @@ protected boolean shouldGenerateIdAsFallback() {
5864
return true;
5965
}
6066

61-
private void useIdAsDatabaseNameIfGiven(Element element, BeanDefinitionBuilder builder) {
62-
String id = element.getAttribute(ID_ATTRIBUTE);
63-
if (StringUtils.hasText(id)) {
64-
builder.addPropertyValue("databaseName", id);
67+
private void setDatabaseName(Element element, BeanDefinitionBuilder builder) {
68+
// 1) Check for an explicit database name
69+
String name = element.getAttribute(DB_NAME_ATTRIBUTE);
70+
71+
// 2) Fall back to an implicit database name based on the ID
72+
if (!StringUtils.hasText(name)) {
73+
name = element.getAttribute(ID_ATTRIBUTE);
6574
}
75+
76+
if (StringUtils.hasText(name)) {
77+
builder.addPropertyValue("databaseName", name);
78+
}
79+
80+
// 3) Let EmbeddedDatabaseFactory set the default "testdb" name
6681
}
6782

6883
private void setDatabaseType(Element element, BeanDefinitionBuilder builder) {

Diff for: spring-jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc-4.2.xsd

+10
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@
3434
</xsd:annotation>
3535
</xsd:element>
3636
</xsd:sequence>
37+
<xsd:attribute name="database-name" type="xsd:string" default="">
38+
<xsd:annotation>
39+
<xsd:documentation><![CDATA[
40+
The name to assign to the embedded database. Note that this is not the
41+
bean name but rather the name of the embedded database as used in the JDBC
42+
connection URL for the database. Defaults to "testdb" if an explicit bean
43+
'id' has not been provided.
44+
]]></xsd:documentation>
45+
</xsd:annotation>
46+
</xsd:attribute>
3747
<xsd:attribute name="type" type="databaseType" default="HSQL">
3848
<xsd:annotation>
3949
<xsd:documentation><![CDATA[

Diff for: spring-jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.java

+26-9
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@
3131
import org.springframework.core.io.ClassPathResource;
3232
import org.springframework.jdbc.BadSqlGrammarException;
3333
import org.springframework.jdbc.core.JdbcTemplate;
34+
import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource;
3435
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean;
3536
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
3637
import org.springframework.tests.Assume;
3738
import org.springframework.tests.TestGroup;
3839

3940
import static org.hamcrest.CoreMatchers.*;
4041
import static org.junit.Assert.*;
42+
import static org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory.*;
4143

4244
/**
4345
* @author Dave Syer
@@ -65,13 +67,24 @@ public void createEmbeddedDatabaseAgain() throws Exception {
6567
}
6668

6769
@Test
68-
public void createWithAnonymousDataSource() throws Exception {
69-
assertCorrectSetupAndCloseContextForSingleDataSource("jdbc-config-anonymous-datasource.xml", 1);
70+
public void createWithResourcePattern() throws Exception {
71+
assertCorrectSetup("jdbc-config-pattern.xml", "dataSource");
7072
}
7173

7274
@Test
73-
public void createWithResourcePattern() throws Exception {
74-
assertCorrectSetup("jdbc-config-pattern.xml", "dataSource");
75+
public void createWithAnonymousDataSourceAndDefaultDatabaseName() throws Exception {
76+
assertCorrectSetupForSingleDataSource("jdbc-config-db-name-default-and-anonymous-datasource.xml",
77+
DEFAULT_DATABASE_NAME);
78+
}
79+
80+
@Test
81+
public void createWithImplicitDatabaseName() throws Exception {
82+
assertCorrectSetupForSingleDataSource("jdbc-config-db-name-implicit.xml", "dataSource");
83+
}
84+
85+
@Test
86+
public void createWithExplicitDatabaseName() throws Exception {
87+
assertCorrectSetupForSingleDataSource("jdbc-config-db-name-explicit.xml", "customDbName");
7588
}
7689

7790
@Test
@@ -165,21 +178,25 @@ private void assertCorrectSetupAndCloseContext(String file, int count, String...
165178
try {
166179
for (String dataSourceName : dataSources) {
167180
DataSource dataSource = context.getBean(dataSourceName, DataSource.class);
168-
JdbcTemplate template = new JdbcTemplate(dataSource);
169-
assertNumRowsInTestTable(template, count);
181+
assertNumRowsInTestTable(new JdbcTemplate(dataSource), count);
182+
assertTrue(dataSource instanceof AbstractDriverBasedDataSource);
183+
AbstractDriverBasedDataSource adbDataSource = (AbstractDriverBasedDataSource) dataSource;
184+
assertThat(adbDataSource.getUrl(), containsString(dataSourceName));
170185
}
171186
}
172187
finally {
173188
context.close();
174189
}
175190
}
176191

177-
private void assertCorrectSetupAndCloseContextForSingleDataSource(String file, int count) {
192+
private void assertCorrectSetupForSingleDataSource(String file, String dbName) {
178193
ConfigurableApplicationContext context = context(file);
179194
try {
180195
DataSource dataSource = context.getBean(DataSource.class);
181-
JdbcTemplate template = new JdbcTemplate(dataSource);
182-
assertNumRowsInTestTable(template, count);
196+
assertNumRowsInTestTable(new JdbcTemplate(dataSource), 1);
197+
assertTrue(dataSource instanceof AbstractDriverBasedDataSource);
198+
AbstractDriverBasedDataSource adbDataSource = (AbstractDriverBasedDataSource) dataSource;
199+
assertThat(adbDataSource.getUrl(), containsString(dbName));
183200
}
184201
finally {
185202
context.close();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns="http://www.springframework.org/schema/jdbc"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5+
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd">
6+
7+
<embedded-database id="dataSource" database-name="customDbName">
8+
<script location="classpath:org/springframework/jdbc/config/db-schema.sql" />
9+
<script location="classpath:org/springframework/jdbc/config/db-test-data.sql" />
10+
</embedded-database>
11+
12+
</beans:beans>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns="http://www.springframework.org/schema/jdbc"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5+
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd">
6+
7+
<embedded-database id="dataSource">
8+
<script location="classpath:org/springframework/jdbc/config/db-schema.sql" />
9+
<script location="classpath:org/springframework/jdbc/config/db-test-data.sql" />
10+
</embedded-database>
11+
12+
</beans:beans>

0 commit comments

Comments
 (0)