diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/AbstractDataSourceConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/AbstractDataSourceConfiguration.java index 898dac2372..7e4c7340b3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/AbstractDataSourceConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/AbstractDataSourceConfiguration.java @@ -16,9 +16,9 @@ package org.springframework.boot.autoconfigure.jdbc; +import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.util.StringUtils; /** @@ -26,8 +26,8 @@ import org.springframework.util.StringUtils; * * @author Dave Syer */ -@ConfigurationProperties(path = "spring.data") -public abstract class AbstractDataSourceConfiguration { +@ConfigurationProperties(path = "spring.datasource") +public abstract class AbstractDataSourceConfiguration implements BeanClassLoaderAware { private String driverClassName; @@ -49,19 +49,25 @@ public abstract class AbstractDataSourceConfiguration { private boolean testOnReturn = false; + private ClassLoader classLoader; + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + protected String getDriverClassName() { if (StringUtils.hasText(this.driverClassName)) { return this.driverClassName; } - EmbeddedDatabaseType embeddedDatabaseType = EmbeddedDatabaseConfiguration - .getEmbeddedDatabaseType(); - this.driverClassName = EmbeddedDatabaseConfiguration - .getEmbeddedDatabaseDriverClass(embeddedDatabaseType); + EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection + .get(this.classLoader); + this.driverClassName = embeddedDatabaseConnection.getDriverClassName(); if (!StringUtils.hasText(this.driverClassName)) { throw new BeanCreationException( "Cannot determine embedded database driver class for database type " - + embeddedDatabaseType - + ". If you want an embedded database please put a supoprted one on the classpath."); + + embeddedDatabaseConnection + ". If you want an embedded " + + "database please put a supoprted one on the classpath."); } return this.driverClassName; } @@ -70,15 +76,14 @@ public abstract class AbstractDataSourceConfiguration { if (StringUtils.hasText(this.url)) { return this.url; } - EmbeddedDatabaseType embeddedDatabaseType = EmbeddedDatabaseConfiguration - .getEmbeddedDatabaseType(); - this.url = EmbeddedDatabaseConfiguration - .getEmbeddedDatabaseUrl(embeddedDatabaseType); + EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection + .get(this.classLoader); + this.url = embeddedDatabaseConnection.getUrl(); if (!StringUtils.hasText(this.url)) { throw new BeanCreationException( "Cannot determine embedded database url for database type " - + embeddedDatabaseType - + ". If you want an embedded database please put a supported on on the classpath."); + + embeddedDatabaseConnection + ". If you want an embedded " + + "database please put a supported on on the classpath."); } return this.url; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/BasicDataSourceConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfiguration.java similarity index 91% rename from spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/BasicDataSourceConfiguration.java rename to spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfiguration.java index 98f8ab4169..1c1879be50 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/BasicDataSourceConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfiguration.java @@ -33,11 +33,12 @@ import org.springframework.dao.DataAccessResourceFailureException; * recommended in high volume environments (the Tomcat DataSource is more reliable). * * @author Dave Syer + * @see DataSourceAutoConfiguration */ @Configuration -public class BasicDataSourceConfiguration extends AbstractDataSourceConfiguration { +public class CommonsDataSourceConfiguration extends AbstractDataSourceConfiguration { - private static Log logger = LogFactory.getLog(BasicDataSourceConfiguration.class); + private static Log logger = LogFactory.getLog(CommonsDataSourceConfiguration.class); private BasicDataSource pool; diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java index 774aae3824..1187a84fc4 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java @@ -26,13 +26,17 @@ import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; +import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.context.ApplicationContext; +import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; @@ -61,7 +65,7 @@ import org.springframework.util.StringUtils; @Configuration @ConditionalOnClass(EmbeddedDatabaseType.class /* Spring JDBC */) @ConditionalOnMissingBean(DataSource.class) -public class DataSourceAutoConfiguration { +public class DataSourceAutoConfiguration implements EnvironmentAware { private static Log logger = LogFactory.getLog(DataSourceAutoConfiguration.class); @@ -71,8 +75,66 @@ public class DataSourceAutoConfiguration { @Autowired private ApplicationContext applicationContext; + private RelaxedPropertyResolver environment; + + @Override + public void setEnvironment(Environment environment) { + this.environment = new RelaxedPropertyResolver(environment, "spring.database."); + } + + @PostConstruct + protected void initialize() throws Exception { + if (this.dataSource == null) { + logger.debug("No DataSource found so not initializing"); + return; + } + + String schema = this.environment.getProperty("schema"); + if (schema == null) { + schema = "classpath*:schema-" + + this.environment.getProperty("platform", "all") + ".sql"; + } + + List resources = new ArrayList(); + for (String schemaLocation : StringUtils.commaDelimitedListToStringArray(schema)) { + resources.addAll(Arrays.asList(this.applicationContext + .getResources(schemaLocation))); + } + + boolean exists = false; + ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); + for (Resource resource : resources) { + if (resource.exists()) { + exists = true; + populator.addScript(resource); + populator.setContinueOnError(true); + } + } + + if (exists) { + DatabasePopulatorUtils.execute(populator, this.dataSource); + } + } + + /** + * Determines if the {@code dataSource} being used by Spring was created from + * {@link EmbeddedDataSourceConfiguration}. + * @return true if the data source was auto-configured. + */ + public static boolean containsAutoConfiguredDataSource( + ConfigurableListableBeanFactory beanFactory) { + try { + BeanDefinition beanDefinition = beanFactory.getBeanDefinition("dataSource"); + return EmbeddedDataSourceConfiguration.class.getName().equals( + beanDefinition.getFactoryBeanName()); + } + catch (NoSuchBeanDefinitionException ex) { + return false; + } + } + @Conditional(DataSourceAutoConfiguration.EmbeddedDatabaseCondition.class) - @Import(EmbeddedDatabaseConfiguration.class) + @Import(EmbeddedDataSourceConfiguration.class) protected static class EmbeddedConfiguration { } @@ -82,7 +144,7 @@ public class DataSourceAutoConfiguration { } @Conditional(DataSourceAutoConfiguration.BasicDatabaseCondition.class) - @Import(BasicDataSourceConfiguration.class) + @Import(CommonsDataSourceConfiguration.class) protected static class DbcpConfiguration { } @@ -107,35 +169,6 @@ public class DataSourceAutoConfiguration { } - @Value("${spring.database.schema:classpath*:schema-${spring.database.platform:all}.sql}") - private String schemaLocations = ""; - - @PostConstruct - protected void initialize() throws Exception { - if (this.dataSource == null) { - logger.debug("No DataSource found so not initializing"); - return; - } - ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); - boolean exists = false; - List resources = new ArrayList(); - for (String location : StringUtils - .commaDelimitedListToStringArray(this.schemaLocations)) { - resources - .addAll(Arrays.asList(this.applicationContext.getResources(location))); - } - for (Resource resource : resources) { - if (resource.exists()) { - exists = true; - populator.addScript(resource); - populator.setContinueOnError(true); - } - } - if (exists) { - DatabasePopulatorUtils.execute(populator, this.dataSource); - } - } - static abstract class NonEmbeddedDatabaseCondition extends SpringBootCondition { protected abstract String getDataSourceClassName(); @@ -149,12 +182,13 @@ public class DataSourceAutoConfiguration { + " DataSource class not found"); } - String driverClassName = getDriverClassName(context.getEnvironment()); + String driverClassName = getDriverClassName(context.getEnvironment(), + context.getClassLoader()); if (driverClassName == null) { return Outcome.noMatch("no database driver"); } - String url = getUrl(context.getEnvironment()); + String url = getUrl(context.getEnvironment(), context.getClassLoader()); if (url == null) { return Outcome.noMatch("no database URL"); } @@ -166,24 +200,21 @@ public class DataSourceAutoConfiguration { return Outcome.match("missing database driver " + driverClassName); } - private String getDriverClassName(Environment environment) { + private String getDriverClassName(Environment environment, ClassLoader classLoader) { String driverClassName = environment == null ? null : environment .getProperty("spring.database.driverClassName"); if (driverClassName == null) { - driverClassName = EmbeddedDatabaseConfiguration - .getEmbeddedDatabaseDriverClass(EmbeddedDatabaseConfiguration - .getEmbeddedDatabaseType()); + driverClassName = EmbeddedDatabaseConnection.get(classLoader) + .getDriverClassName(); } return driverClassName; } - private String getUrl(Environment environment) { + private String getUrl(Environment environment, ClassLoader classLoader) { String url = (environment == null ? null : environment .getProperty("spring.database.url")); if (url == null) { - url = EmbeddedDatabaseConfiguration - .getEmbeddedDatabaseUrl(EmbeddedDatabaseConfiguration - .getEmbeddedDatabaseType()); + url = EmbeddedDatabaseConnection.get(classLoader).getUrl(); } return url; } @@ -229,8 +260,8 @@ public class DataSourceAutoConfiguration { if (anyMatches(context, metadata, this.tomcatCondition, this.dbcpCondition)) { return Outcome.noMatch("existing non-embedded database detected"); } - EmbeddedDatabaseType type = EmbeddedDatabaseConfiguration - .getEmbeddedDatabaseType(); + EmbeddedDatabaseType type = EmbeddedDatabaseConnection.get( + context.getClassLoader()).getType(); if (type == null) { return Outcome.noMatch("no embedded database detected"); } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfiguration.java new file mode 100644 index 0000000000..b134694288 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfiguration.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jdbc; + +import javax.annotation.PreDestroy; +import javax.sql.DataSource; + +import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; + +/** + * Configuration for embedded data sources. + * + * @author Phillip Webb + * @see DataSourceAutoConfiguration + */ +@Configuration +public class EmbeddedDataSourceConfiguration implements BeanClassLoaderAware { + + private EmbeddedDatabase database; + + private ClassLoader classLoader; + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Bean + public DataSource dataSource() { + EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseConnection.get(this.classLoader).getType()); + this.database = builder.build(); + return this.database; + } + + @PreDestroy + public void close() { + if (this.database != null) { + this.database.shutdown(); + } + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java deleted file mode 100644 index 26b9444a83..0000000000 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2012-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.jdbc; - -import java.util.LinkedHashMap; -import java.util.Map; - -import javax.annotation.PreDestroy; -import javax.sql.DataSource; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; -import org.springframework.util.ClassUtils; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for embedded databases. - * - * @author Phillip Webb - */ -@Configuration -public class EmbeddedDatabaseConfiguration { - - private static final Map EMBEDDED_DATABASE_DRIVER_CLASSES; - static { - Map drivers = new LinkedHashMap(); - drivers.put(EmbeddedDatabaseType.H2, "org.h2.Driver"); - drivers.put(EmbeddedDatabaseType.DERBY, "org.apache.derby.jdbc.EmbeddedDriver"); - drivers.put(EmbeddedDatabaseType.HSQL, "org.hsqldb.jdbcDriver"); - EMBEDDED_DATABASE_DRIVER_CLASSES = drivers; - } - - private static final Map EMBEDDED_DATABASE_URLS; - static { - Map urls = new LinkedHashMap(); - urls.put(EmbeddedDatabaseType.H2, "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1"); - urls.put(EmbeddedDatabaseType.DERBY, "jdbc:derby:memory:testdb;create=true"); - urls.put(EmbeddedDatabaseType.HSQL, "jdbc:hsqldb:mem:testdb"); - EMBEDDED_DATABASE_URLS = urls; - } - - private EmbeddedDatabase database; - - @Bean - public DataSource dataSource() { - EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder() - .setType(getEmbeddedDatabaseType()); - this.database = builder.build(); - return this.database; - } - - @PreDestroy - public void close() { - if (this.database != null) { - this.database.shutdown(); - } - } - - public static String getEmbeddedDatabaseDriverClass( - EmbeddedDatabaseType embeddedDatabaseType) { - return EMBEDDED_DATABASE_DRIVER_CLASSES.get(embeddedDatabaseType); - } - - public static String getEmbeddedDatabaseUrl(EmbeddedDatabaseType embeddedDatabaseType) { - return EMBEDDED_DATABASE_URLS.get(embeddedDatabaseType); - } - - public static EmbeddedDatabaseType getEmbeddedDatabaseType() { - for (Map.Entry entry : EMBEDDED_DATABASE_DRIVER_CLASSES - .entrySet()) { - if (ClassUtils.isPresent(entry.getValue(), - EmbeddedDatabaseConfiguration.class.getClassLoader())) { - return entry.getKey(); - } - } - return null; - } - -} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDatabaseConnection.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDatabaseConnection.java new file mode 100644 index 0000000000..3e961db5fb --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDatabaseConnection.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jdbc; + +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.util.ClassUtils; + +/** + * Connection details for {@link EmbeddedDatabaseType embedded databases}. + * + * @author Phillip Webb + * @author Dave Syer + * @see #get(ClassLoader) + */ +public enum EmbeddedDatabaseConnection { + + /** + * No Connection. + */ + NONE(null, null, null), + + /** + * H2 Database Connection. + */ + H2(EmbeddedDatabaseType.H2, "org.h2.Driver", "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1"), + + /** + * Derby Database Connection. + */ + DERBY(EmbeddedDatabaseType.DERBY, "org.apache.derby.jdbc.EmbeddedDriver", + "jdbc:derby:memory:testdb;create=true"), + + /** + * HSQL Database Connection. + */ + HSQL(EmbeddedDatabaseType.HSQL, "org.hsqldb.jdbcDriver", "jdbc:hsqldb:mem:testdb"); + + private final EmbeddedDatabaseType type; + + private final String driverClass; + + private final String url; + + private EmbeddedDatabaseConnection(EmbeddedDatabaseType type, String driverClass, + String url) { + this.type = type; + this.driverClass = driverClass; + this.url = url; + } + + /** + * Returns the driver class name. + */ + public String getDriverClassName() { + return this.driverClass; + } + + /** + * Returns the {@link EmbeddedDatabaseType} for the connection. + */ + public EmbeddedDatabaseType getType() { + return this.type; + } + + /** + * Returns the URL for the connection. + */ + public String getUrl() { + return this.url; + } + + /** + * Override for testing. + */ + static EmbeddedDatabaseConnection override; + + /** + * Returns the most suitable {@link EmbeddedDatabaseConnection} for the given class + * loader. + * @param classLoader the class loader used to check for classes + * @return an {@link EmbeddedDatabaseConnection} or {@link #NONE}. + */ + public static EmbeddedDatabaseConnection get(ClassLoader classLoader) { + if (override != null) { + return override; + } + for (EmbeddedDatabaseConnection candidate : EmbeddedDatabaseConnection.values()) { + if (candidate != NONE + && ClassUtils.isPresent(candidate.getDriverClassName(), classLoader)) { + return candidate; + } + } + return NONE; + } +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfiguration.java index de24c3197a..464499407a 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfiguration.java @@ -27,6 +27,7 @@ import org.springframework.context.annotation.Configuration; * and tends not to deadlock in high volume environments. * * @author Dave Syer + * @see DataSourceAutoConfiguration */ @Configuration public class TomcatDataSourceConfiguration extends AbstractDataSourceConfiguration { diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java index 748260eceb..470f8812ba 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java @@ -16,23 +16,19 @@ package org.springframework.boot.autoconfigure.orm.jpa; -import java.util.LinkedHashMap; import java.util.Map; import org.hibernate.cfg.ImprovedNamingStrategy; import org.hibernate.ejb.HibernateEntityManager; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.Bean; +import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; -import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.core.env.Environment; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.Database; +import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.springframework.util.StringUtils; /** * {@link EnableAutoConfiguration Auto-configuration} for Hibernate JPA. @@ -44,56 +40,31 @@ import org.springframework.util.StringUtils; @EnableTransactionManagement public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration { - private static final Map EMBEDDED_DATABASE_DIALECTS; - static { - EMBEDDED_DATABASE_DIALECTS = new LinkedHashMap(); - EMBEDDED_DATABASE_DIALECTS.put(EmbeddedDatabaseType.HSQL, - "org.hibernate.dialect.HSQLDialect"); + private RelaxedPropertyResolver environment; + + @Override + public void setEnvironment(Environment environment) { + super.setEnvironment(environment); + this.environment = new RelaxedPropertyResolver(environment, + "spring.jpa.hibernate."); } - @Value("${spring.jpa.databasePlatform:${spring.jpa.database_platform:}}") - private String databasePlatform; - - @Value("${spring.jpa.database:DEFAULT}") - private Database database = Database.DEFAULT; - - @Value("${spring.jpa.showSql:${spring.jpa.show_sql:true}}") - private boolean showSql; - - @Value("${spring.jpa.ddlAuto:${spring.jpa.ddl_auto:none}}") - private String ddlAuto; // e.g. none, validate, update, create, create-drop - - @Value("${spring.jpa.hibernate.namingstrategy:org.hibernate.cfg.ImprovedNamingStrategy}") - private String namingStrategy; - - @Bean @Override - public JpaVendorAdapter jpaVendorAdapter() { - HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); - adapter.setShowSql(this.showSql); - if (StringUtils.hasText(this.databasePlatform)) { - adapter.setDatabasePlatform(this.databasePlatform); - } - adapter.setDatabase(this.database); - return adapter; + protected AbstractJpaVendorAdapter createJpaVendorAdapter() { + return new HibernateJpaVendorAdapter(); } @Override protected void configure( LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) { Map properties = entityManagerFactoryBean.getJpaPropertyMap(); - properties.put("hibernate.cache.provider_class", - "org.hibernate.cache.HashtableCacheProvider"); - if (StringUtils.hasLength(this.namingStrategy)) { - properties.put("hibernate.ejb.naming_strategy", this.namingStrategy); - } - else { - properties.put("hibernate.ejb.naming_strategy", - ImprovedNamingStrategy.class.getName()); - } - if (StringUtils.hasLength(this.ddlAuto) && !"none".equals(this.ddlAuto)) { - properties.put("hibernate.hbm2ddl.auto", this.ddlAuto); + properties.put("hibernate.cache.provider_class", this.environment.getProperty( + "cache-provider", "org.hibernate.cache.HashtableCacheProvider")); + properties.put("hibernate.ejb.naming_strategy", this.environment.getProperty( + "naming-strategy", ImprovedNamingStrategy.class.getName())); + String ddlAuto = this.environment.getProperty("ddl-auto", "none"); + if (!"none".equals(ddlAuto)) { + properties.put("hibernate.hbm2ddl.auto", ddlAuto); } } - } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java index 45305dac65..1dbb22cd45 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java @@ -24,8 +24,6 @@ import javax.sql.DataSource; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.boot.autoconfigure.AutoConfigurationUtils; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -34,14 +32,18 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConfiguration; +import org.springframework.boot.bind.RelaxedPropertyResolver; +import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter; import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor; +import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter; +import org.springframework.orm.jpa.vendor.Database; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.util.Assert; @@ -57,10 +59,17 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter @ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EnableTransactionManagement.class, EntityManager.class }) @ConditionalOnBean(DataSource.class) -public abstract class JpaBaseConfiguration implements BeanFactoryAware { +public abstract class JpaBaseConfiguration implements BeanFactoryAware, EnvironmentAware { private ConfigurableListableBeanFactory beanFactory; + private RelaxedPropertyResolver environment; + + @Override + public void setEnvironment(Environment environment) { + this.environment = new RelaxedPropertyResolver(environment, "spring.jpa."); + } + @Bean public PlatformTransactionManager transactionManager() { return new JpaTransactionManager(entityManagerFactory().getObject()); @@ -72,29 +81,25 @@ public abstract class JpaBaseConfiguration implements BeanFactoryAware { entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter()); entityManagerFactoryBean.setDataSource(getDataSource()); entityManagerFactoryBean.setPackagesToScan(getPackagesToScan()); + entityManagerFactoryBean.getJpaPropertyMap().putAll( + this.environment.getSubProperties("properties.")); configure(entityManagerFactoryBean); return entityManagerFactoryBean; } - /** - * Determines if the {@code dataSource} being used by Spring was created from - * {@link EmbeddedDatabaseConfiguration}. - * @return true if the data source was auto-configured. - */ - protected boolean isAutoConfiguredDataSource() { - try { - BeanDefinition beanDefinition = this.beanFactory - .getBeanDefinition("dataSource"); - return EmbeddedDatabaseConfiguration.class.getName().equals( - beanDefinition.getFactoryBeanName()); - } - catch (NoSuchBeanDefinitionException ex) { - return false; - } + @Bean + public JpaVendorAdapter jpaVendorAdapter() { + AbstractJpaVendorAdapter adapter = createJpaVendorAdapter(); + adapter.setShowSql(this.environment.getProperty("show-sql", Boolean.class, true)); + adapter.setDatabasePlatform(this.environment.getProperty("database-platform")); + adapter.setDatabase(this.environment.getProperty("database", Database.class, + Database.DEFAULT)); + adapter.setGenerateDdl(this.environment.getProperty("generate-ddl", + Boolean.class, false)); + return adapter; } - @Bean - public abstract JpaVendorAdapter jpaVendorAdapter(); + protected abstract AbstractJpaVendorAdapter createJpaVendorAdapter(); protected DataSource getDataSource() { try { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java index a2c0f4c5be..bf8ce57c49 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java @@ -21,10 +21,9 @@ import javax.persistence.EntityManagerFactory; import org.junit.Test; import org.springframework.boot.autoconfigure.ComponentScanDetectorConfiguration; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.JpaRepositoriesAutoConfiguration; import org.springframework.boot.autoconfigure.data.test.City; import org.springframework.boot.autoconfigure.data.test.CityRepository; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConfiguration; +import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; @@ -35,7 +34,7 @@ import static org.junit.Assert.assertNotNull; /** * Tests for {@link JpaRepositoriesAutoConfiguration}. - * + * * @author Dave Syer */ public class JpaRepositoriesAutoConfigurationTests { @@ -47,7 +46,7 @@ public class JpaRepositoriesAutoConfigurationTests { this.context = new AnnotationConfigApplicationContext(); this.context.register(TestConfiguration.class, ComponentScanDetectorConfiguration.class, - EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class, + EmbeddedDataSourceConfiguration.class, HibernateJpaAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaWebAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaWebAutoConfigurationTests.java index 0c70b62833..d81b3917ad 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaWebAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/JpaWebAutoConfigurationTests.java @@ -22,7 +22,7 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati import org.springframework.boot.autoconfigure.data.JpaRepositoriesAutoConfiguration; import org.springframework.boot.autoconfigure.data.test.City; import org.springframework.boot.autoconfigure.data.test.CityRepository; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConfiguration; +import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -46,7 +46,7 @@ public class JpaWebAutoConfigurationTests { this.context = new AnnotationConfigWebApplicationContext(); this.context.setServletContext(new MockServletContext()); this.context.register(TestConfiguration.class, - EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class, + EmbeddedDataSourceConfiguration.class, HibernateJpaAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/BasicDataSourceConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfigurationTests.java similarity index 82% rename from spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/BasicDataSourceConfigurationTests.java rename to spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfigurationTests.java index 99f6c2ef5a..f7f2c13500 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/BasicDataSourceConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfigurationTests.java @@ -19,23 +19,23 @@ package org.springframework.boot.autoconfigure.jdbc; import javax.sql.DataSource; import org.junit.Test; -import org.springframework.boot.autoconfigure.jdbc.BasicDataSourceConfiguration; +import org.springframework.boot.autoconfigure.jdbc.CommonsDataSourceConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import static org.junit.Assert.assertNotNull; /** - * Tests for {@link BasicDataSourceConfiguration}. + * Tests for {@link CommonsDataSourceConfiguration}. * * @author Dave Syer */ -public class BasicDataSourceConfigurationTests { +public class CommonsDataSourceConfigurationTests { private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); @Test public void testDataSourceExists() throws Exception { - this.context.register(BasicDataSourceConfiguration.class); + this.context.register(CommonsDataSourceConfiguration.class); this.context.refresh(); assertNotNull(this.context.getBean(DataSource.class)); this.context.close(); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java index 9ef2d637b8..5595d8c026 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java @@ -20,7 +20,7 @@ import javax.sql.DataSource; import org.junit.Test; import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConfiguration; +import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.jdbc.datasource.DataSourceTransactionManager; @@ -38,7 +38,7 @@ public class DataSourceTransactionManagerAutoConfigurationTests { @Test public void testDataSourceExists() throws Exception { - this.context.register(EmbeddedDatabaseConfiguration.class, + this.context.register(EmbeddedDataSourceConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class); this.context.refresh(); assertNotNull(this.context.getBean(DataSource.class)); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDatabaseConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfigurationTests.java similarity index 82% rename from spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDatabaseConfigurationTests.java rename to spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfigurationTests.java index b882fc1123..f996638292 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDatabaseConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfigurationTests.java @@ -19,24 +19,24 @@ package org.springframework.boot.autoconfigure.jdbc; import javax.sql.DataSource; import org.junit.Test; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConfiguration; +import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import static org.junit.Assert.assertNotNull; /** - * Tests for {@link EmbeddedDatabaseConfiguration}. + * Tests for {@link EmbeddedDataSourceConfiguration}. * * @author Dave Syer */ -public class EmbeddedDatabaseConfigurationTests { +public class EmbeddedDataSourceConfigurationTests { private AnnotationConfigApplicationContext context; @Test public void testDefaultEmbeddedDatabase() throws Exception { this.context = new AnnotationConfigApplicationContext(); - this.context.register(EmbeddedDatabaseConfiguration.class); + this.context.register(EmbeddedDataSourceConfiguration.class); this.context.refresh(); assertNotNull(this.context.getBean(DataSource.class)); this.context.close(); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java index 9adf36b384..f9f25bc396 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java @@ -17,8 +17,6 @@ package org.springframework.boot.autoconfigure.jdbc; import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; import javax.sql.DataSource; @@ -26,8 +24,6 @@ import org.junit.After; import org.junit.Test; import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConfiguration; -import org.springframework.boot.autoconfigure.jdbc.TomcatDataSourceConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.util.ReflectionUtils; @@ -42,15 +38,9 @@ public class TomcatDataSourceConfigurationTests { private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - private Map old; - - private Map map; - @After public void restore() { - if (this.map != null && this.old != null) { - this.map.putAll(this.old); - } + EmbeddedDatabaseConnection.override = null; } @Test @@ -62,9 +52,7 @@ public class TomcatDataSourceConfigurationTests { @Test(expected = BeanCreationException.class) public void testBadUrl() throws Exception { - this.map = getField(EmbeddedDatabaseConfiguration.class, "EMBEDDED_DATABASE_URLS"); - this.old = new HashMap(this.map); - this.map.clear(); + EmbeddedDatabaseConnection.override = EmbeddedDatabaseConnection.NONE; this.context.register(TomcatDataSourceConfiguration.class, PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); @@ -73,10 +61,7 @@ public class TomcatDataSourceConfigurationTests { @Test(expected = BeanCreationException.class) public void testBadDriverClass() throws Exception { - this.map = getField(EmbeddedDatabaseConfiguration.class, - "EMBEDDED_DATABASE_DRIVER_CLASSES"); - this.old = new HashMap(this.map); - this.map.clear(); + EmbeddedDatabaseConnection.override = EmbeddedDatabaseConnection.NONE; this.context.register(TomcatDataSourceConfiguration.class, PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java new file mode 100644 index 0000000000..e3bfcfae4d --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java @@ -0,0 +1,162 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.orm.jpa; + +import java.util.Map; + +import javax.sql.DataSource; + +import org.junit.After; +import org.junit.Test; +import org.springframework.boot.TestUtils; +import org.springframework.boot.autoconfigure.ComponentScanDetectorConfiguration; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.test.City; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter; +import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +/** + * Base for JPA tests and tests for {@link JpaBaseConfiguration}. + * + * @author Phillip Webb + * @author Dave Syer + */ +public abstract class AbstractJpaAutoConfigurationTests { + + protected AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + @After + public void close() { + this.context.close(); + } + + protected abstract Class getAutoConfigureClass(); + + @Test + public void testEntityManagerCreated() throws Exception { + setupTestConfiguration(); + this.context.refresh(); + assertNotNull(this.context.getBean(DataSource.class)); + assertNotNull(this.context.getBean(JpaTransactionManager.class)); + } + + @Test + public void testDataSourceTransactionManagerNotCreated() throws Exception { + setupTestConfiguration(); + this.context.register(DataSourceTransactionManagerAutoConfiguration.class); + this.context.refresh(); + assertNotNull(this.context.getBean(DataSource.class)); + assertTrue(this.context.getBean("transactionManager") instanceof JpaTransactionManager); + } + + @Test + public void testOpenEntityManagerInViewInterceptorCreated() throws Exception { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.register(TestConfiguration.class, + ComponentScanDetectorConfiguration.class, + EmbeddedDataSourceConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, getAutoConfigureClass()); + context.refresh(); + assertNotNull(context.getBean(OpenEntityManagerInViewInterceptor.class)); + context.close(); + } + + @Test + public void testOpenEntityManagerInViewInterceptorNotRegisteredWhenFilterPresent() + throws Exception { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.register(TestFilterConfiguration.class, + ComponentScanDetectorConfiguration.class, + EmbeddedDataSourceConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, getAutoConfigureClass()); + context.refresh(); + assertEquals(0, getInterceptorBeans(context).length); + context.close(); + } + + @Test + public void testOpenEntityManagerInViewInterceptorNotRegisteredWhenExplicitlyOff() + throws Exception { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + TestUtils.addEnviroment(context, "spring.jpa.open_in_view:false"); + context.register(TestConfiguration.class, + ComponentScanDetectorConfiguration.class, + EmbeddedDataSourceConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, getAutoConfigureClass()); + context.refresh(); + assertEquals(0, getInterceptorBeans(context).length); + context.close(); + } + + @Test + public void customJpaProperties() throws Exception { + TestUtils.addEnviroment(this.context, "spring.jpa.properties.a:b", + "spring.jpa.properties.c:d"); + setupTestConfiguration(); + this.context.refresh(); + LocalContainerEntityManagerFactoryBean bean = this.context + .getBean(LocalContainerEntityManagerFactoryBean.class); + Map map = bean.getJpaPropertyMap(); + assertThat(map.get("a"), equalTo((Object) "b")); + assertThat(map.get("c"), equalTo((Object) "d")); + } + + protected void setupTestConfiguration() { + this.context.register(TestConfiguration.class, + ComponentScanDetectorConfiguration.class, + EmbeddedDataSourceConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, getAutoConfigureClass()); + } + + private String[] getInterceptorBeans(ApplicationContext context) { + return context.getBeanNamesForType(OpenEntityManagerInViewInterceptor.class); + } + + @Configuration + @ComponentScan(basePackageClasses = { City.class }) + protected static class TestConfiguration { + + } + + @Configuration + @ComponentScan(basePackageClasses = { City.class }) + protected static class TestFilterConfiguration { + + @Bean + public OpenEntityManagerInViewFilter openEntityManagerInViewFilter() { + return new OpenEntityManagerInViewFilter(); + } + + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java index 91ca92fc18..c1aecb4abe 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java @@ -16,121 +16,31 @@ package org.springframework.boot.autoconfigure.orm.jpa; -import javax.sql.DataSource; - -import org.junit.After; import org.junit.Test; import org.springframework.boot.TestUtils; -import org.springframework.boot.autoconfigure.ComponentScanDetectorConfiguration; -import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.test.City; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter; -import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor; -import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; /** * Tests for {@link HibernateJpaAutoConfiguration}. * * @author Dave Syer + * @author Phillip Webb */ -public class HibernateJpaAutoConfigurationTests { +public class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTests { - private ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - - @After - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void testEntityManagerCreated() throws Exception { - ((AnnotationConfigApplicationContext) this.context).register( - ComponentScanDetectorConfiguration.class, - EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class); - this.context.refresh(); - assertNotNull(this.context.getBean(DataSource.class)); - assertNotNull(this.context.getBean(JpaTransactionManager.class)); - } - - @Test - public void testDataSourceTransactionManagerNotCreated() throws Exception { - ((AnnotationConfigApplicationContext) this.context).register( - ComponentScanDetectorConfiguration.class, - EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class, - DataSourceTransactionManagerAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class); - this.context.refresh(); - assertNotNull(this.context.getBean(DataSource.class)); - assertTrue(this.context.getBean("transactionManager") instanceof JpaTransactionManager); - } - - @Test - public void testOpenEntityManagerInViewInterceptorCreated() throws Exception { - AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); - context.register(ComponentScanDetectorConfiguration.class, - EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class); - this.context = context; - this.context.refresh(); - assertNotNull(this.context.getBean(OpenEntityManagerInViewInterceptor.class)); - } - - @Test - public void testOpenEntityManagerInViewInterceptorNotRegisteredWhenFilterPresent() - throws Exception { - AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); - context.register(TestFilterConfiguration.class, - ComponentScanDetectorConfiguration.class, - EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context = context; - this.context.refresh(); - assertEquals(0, getInterceptorBeans().length); - } - - @Test - public void testOpenEntityManagerInViewInterceptorNotRegisteredWhenExplicitlyOff() - throws Exception { - AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); - TestUtils.addEnviroment(context, "spring.jpa.open_in_view:false"); - context.register(TestConfiguration.class, - ComponentScanDetectorConfiguration.class, - EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context = context; - this.context.refresh(); - assertEquals(0, getInterceptorBeans().length); + @Override + protected Class getAutoConfigureClass() { + return HibernateJpaAutoConfiguration.class; } @Test public void testCustomNamingStrategy() throws Exception { - AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); - TestUtils - .addEnviroment(context, - "spring.jpa.hibernate.namingstrategy:org.hibernate.cfg.EJB3NamingStrategy"); - context.register(TestConfiguration.class, - ComponentScanDetectorConfiguration.class, - EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context = context; + TestUtils.addEnviroment(this.context, "spring.jpa.hibernate.namingstrategy:" + + "org.hibernate.cfg.EJB3NamingStrategy"); + setupTestConfiguration(); this.context.refresh(); LocalContainerEntityManagerFactoryBean bean = this.context .getBean(LocalContainerEntityManagerFactoryBean.class); @@ -139,21 +49,4 @@ public class HibernateJpaAutoConfigurationTests { assertThat(actual, equalTo("org.hibernate.cfg.EJB3NamingStrategy")); } - private String[] getInterceptorBeans() { - return this.context.getBeanNamesForType(OpenEntityManagerInViewInterceptor.class); - } - - @ComponentScan(basePackageClasses = { City.class }) - protected static class TestConfiguration { - - } - - @ComponentScan(basePackageClasses = { City.class }) - @Configuration - protected static class TestFilterConfiguration { - @Bean - public OpenEntityManagerInViewFilter openEntityManagerInViewFilter() { - return new OpenEntityManagerInViewFilter(); - } - } } diff --git a/spring-boot-samples/spring-boot-sample-data-jpa/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-data-jpa/src/main/resources/application.properties index 2793254e4e..948b0917f6 100644 --- a/spring-boot-samples/spring-boot-sample-data-jpa/src/main/resources/application.properties +++ b/spring-boot-samples/spring-boot-sample-data-jpa/src/main/resources/application.properties @@ -1 +1 @@ -spring.jpa.ddl_auto: create-drop \ No newline at end of file +spring.jpa.hibernate.ddl-auto: create-drop