SPR-7604 - Support multiple embedded databases.
Embedded datasources now get their bean ids set as database name to allow multiple databases of the same type in parallel. Refactored tests a little and made BeanDefinitionParser package private to align with the other ones. Adapted changelog accordingly.
This commit is contained in:
parent
5918e2fa9c
commit
ba2bac17de
|
|
@ -18,6 +18,8 @@ Changes in version 3.0.5 (2010-10-13)
|
||||||
* AspectJExpressionPointcut uses bean ClassLoader for initializing the AspectJ pointcut parser
|
* AspectJExpressionPointcut uses bean ClassLoader for initializing the AspectJ pointcut parser
|
||||||
* JDBC bundle uses local ClassLoader as bean ClassLoader for "sql-error-codes.xml" parsing
|
* JDBC bundle uses local ClassLoader as bean ClassLoader for "sql-error-codes.xml" parsing
|
||||||
* EmbeddedDatabaseFactory shuts down database when failing to populate it in "initDatabase()"
|
* EmbeddedDatabaseFactory shuts down database when failing to populate it in "initDatabase()"
|
||||||
|
* embedded database support now also works with Derby >= 10.6
|
||||||
|
* "jdbc:embedded-database" uses id as database name to allow multiple ones in parallel
|
||||||
* DefaultLobHandler's "wrapAsLob" mode works with PostgreSQL's "getAsciiStream()" requirement
|
* DefaultLobHandler's "wrapAsLob" mode works with PostgreSQL's "getAsciiStream()" requirement
|
||||||
* ResultSetWrappingSqlRowSet (as used by JdbcTemplate's "queryForRowSet") supports column labels now
|
* ResultSetWrappingSqlRowSet (as used by JdbcTemplate's "queryForRowSet") supports column labels now
|
||||||
* LocalSessionFactoryBean's "entityCacheStrategies" works with region names on Hibernate 3.6 as well
|
* LocalSessionFactoryBean's "entityCacheStrategies" works with region names on Hibernate 3.6 as well
|
||||||
|
|
|
||||||
|
|
@ -38,16 +38,27 @@ import org.w3c.dom.Element;
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||||
|
|
||||||
|
private static final String NAME_PROPERTY = "databaseName";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext context) {
|
protected AbstractBeanDefinition parseInternal(Element element, ParserContext context) {
|
||||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(EmbeddedDatabaseFactoryBean.class);
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(EmbeddedDatabaseFactoryBean.class);
|
||||||
setDatabaseType(element, builder);
|
setDatabaseType(element, builder);
|
||||||
setDatabasePopulator(element, context, builder);
|
setDatabasePopulator(element, context, builder);
|
||||||
|
useIdAsDatabaseNameIfGiven(element, builder);
|
||||||
return getSourcedBeanDefinition(builder, element, context);
|
return getSourcedBeanDefinition(builder, element, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void useIdAsDatabaseNameIfGiven(Element element, BeanDefinitionBuilder builder) {
|
||||||
|
|
||||||
|
String id = element.getAttribute(ID_ATTRIBUTE);
|
||||||
|
if (StringUtils.hasText(id)) {
|
||||||
|
builder.addPropertyValue(NAME_PROPERTY, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setDatabaseType(Element element, BeanDefinitionBuilder builder) {
|
private void setDatabaseType(Element element, BeanDefinitionBuilder builder) {
|
||||||
String type = element.getAttribute("type");
|
String type = element.getAttribute("type");
|
||||||
if (StringUtils.hasText(type)) {
|
if (StringUtils.hasText(type)) {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
package org.springframework.jdbc.config;
|
package org.springframework.jdbc.config;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.PropertyValue;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.xml.XmlBeanFactory;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
|
||||||
public class JdbcNamespaceIntegrationTest {
|
public class JdbcNamespaceIntegrationTest {
|
||||||
|
|
@ -14,13 +21,7 @@ public class JdbcNamespaceIntegrationTest {
|
||||||
public void testCreateEmbeddedDatabase() throws Exception {
|
public void testCreateEmbeddedDatabase() throws Exception {
|
||||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||||
"org/springframework/jdbc/config/jdbc-config.xml");
|
"org/springframework/jdbc/config/jdbc-config.xml");
|
||||||
try {
|
assertCorrectSetup(context, "dataSource", "h2DataSource", "derbyDataSource");
|
||||||
assertCorrectSetup(context.getBean("dataSource", DataSource.class));
|
|
||||||
assertCorrectSetup(context.getBean("h2DataSource", DataSource.class));
|
|
||||||
assertCorrectSetup(context.getBean("derbyDataSource", DataSource.class));
|
|
||||||
} finally {
|
|
||||||
context.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -28,26 +29,44 @@ public class JdbcNamespaceIntegrationTest {
|
||||||
// If Derby isn't cleaned up properly this will fail...
|
// If Derby isn't cleaned up properly this will fail...
|
||||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||||
"org/springframework/jdbc/config/jdbc-config.xml");
|
"org/springframework/jdbc/config/jdbc-config.xml");
|
||||||
try {
|
assertCorrectSetup(context, "derbyDataSource");
|
||||||
assertCorrectSetup(context.getBean("derbyDataSource", DataSource.class));
|
|
||||||
} finally {
|
|
||||||
context.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateWithResourcePattern() throws Exception {
|
public void testCreateWithResourcePattern() throws Exception {
|
||||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||||
"org/springframework/jdbc/config/jdbc-config-pattern.xml");
|
"org/springframework/jdbc/config/jdbc-config-pattern.xml");
|
||||||
|
assertCorrectSetup(context, "dataSource");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultipleDataSourcesHaveDifferentDatabaseNames() throws Exception {
|
||||||
|
|
||||||
|
DefaultListableBeanFactory factory = new XmlBeanFactory(new ClassPathResource(
|
||||||
|
"org/springframework/jdbc/config/jdbc-config-multiple-datasources.xml"));
|
||||||
|
|
||||||
|
assertBeanPropertyValueOf("databaseName", "firstDataSource", factory);
|
||||||
|
assertBeanPropertyValueOf("databaseName", "secondDataSource", factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertBeanPropertyValueOf(String propertyName, String expected, DefaultListableBeanFactory factory) {
|
||||||
|
|
||||||
|
BeanDefinition bean = factory.getBeanDefinition(expected);
|
||||||
|
PropertyValue value = bean.getPropertyValues().getPropertyValue(propertyName);
|
||||||
|
assertThat(value, is(notNullValue()));
|
||||||
|
assertThat(value.getValue().toString(), is(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertCorrectSetup(ConfigurableApplicationContext context, String... dataSources) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assertCorrectSetup(context.getBean("dataSource", DataSource.class));
|
for (String dataSourceName : dataSources) {
|
||||||
|
DataSource dataSource = context.getBean(dataSourceName, DataSource.class);
|
||||||
|
JdbcTemplate t = new JdbcTemplate(dataSource);
|
||||||
|
assertEquals(1, t.queryForInt("select count(*) from T_TEST"));
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertCorrectSetup(DataSource dataSource) {
|
|
||||||
JdbcTemplate t = new JdbcTemplate(dataSource);
|
|
||||||
assertEquals(1, t.queryForInt("select count(*) from T_TEST"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue