diff --git a/spring-autoconfigure/pom.xml b/spring-autoconfigure/pom.xml
index 838ba74b9fd..2cc0fcccec5 100644
--- a/spring-autoconfigure/pom.xml
+++ b/spring-autoconfigure/pom.xml
@@ -118,5 +118,10 @@
spring-test
test
+
+ org.slf4j
+ slf4j-jdk14
+ test
+
diff --git a/spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java b/spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java
index f01a4d105fb..eb658a2d963 100644
--- a/spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java
+++ b/spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java
@@ -41,7 +41,7 @@ import org.springframework.util.StringUtils;
@Configuration
@ConditionalOnClass(HibernateEntityManager.class)
@EnableTransactionManagement
-public class HibernateJpaAutoConfiguration extends JpaAutoConfiguration {
+public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
private static final Map EMBEDDED_DATABASE_DIALECTS;
static {
diff --git a/spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/JpaAutoConfiguration.java b/spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/JpaBaseConfiguration.java
similarity index 63%
rename from spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/JpaAutoConfiguration.java
rename to spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/JpaBaseConfiguration.java
index c11f9b39946..2e5fcd33c45 100644
--- a/spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/JpaAutoConfiguration.java
+++ b/spring-autoconfigure/src/main/java/org/springframework/autoconfigure/orm/jpa/JpaBaseConfiguration.java
@@ -32,23 +32,32 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.bootstrap.context.condition.ConditionalOnBean;
import org.springframework.bootstrap.context.condition.ConditionalOnClass;
+import org.springframework.bootstrap.context.condition.ConditionalOnExpression;
+import org.springframework.bootstrap.context.condition.ConditionalOnMissingBean;
+import org.springframework.bootstrap.context.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
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.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.Assert;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Base {@link EnableAutoConfiguration Auto-configuration} for JPA.
*
* @author Phillip Webb
+ * @author Dave Syer
*/
-@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class,
- EnableTransactionManagement.class, EntityManager.class })
+@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EnableTransactionManagement.class,
+ EntityManager.class })
@ConditionalOnBean(DataSource.class)
-public abstract class JpaAutoConfiguration implements BeanFactoryAware {
+public abstract class JpaBaseConfiguration implements BeanFactoryAware {
private ConfigurableListableBeanFactory beanFactory;
@@ -67,19 +76,33 @@ public abstract class JpaAutoConfiguration implements BeanFactoryAware {
return entityManagerFactoryBean;
}
+ @Configuration
+ @ConditionalOnWebApplication
+ @ConditionalOnMissingBean({ OpenEntityManagerInViewInterceptor.class, OpenEntityManagerInViewFilter.class })
+ @ConditionalOnExpression("${spring.jpa.openInView:${spring.jpa.open_in_view:true}}")
+ protected static class JpaWebConfiguration extends WebMvcConfigurerAdapter {
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ super.addInterceptors(registry);
+ }
+
+ @Bean
+ public OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor() {
+ return new OpenEntityManagerInViewInterceptor();
+ }
+
+ }
+
/**
- * Determines if the {@code dataSource} being used by Spring was created from
- * {@link EmbeddedDatabaseConfiguration}.
+ * 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) {
+ BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition("dataSource");
+ return EmbeddedDatabaseConfiguration.class.getName().equals(beanDefinition.getFactoryBeanName());
+ } catch (NoSuchBeanDefinitionException ex) {
return false;
}
}
@@ -90,23 +113,19 @@ public abstract class JpaAutoConfiguration implements BeanFactoryAware {
protected DataSource getDataSource() {
try {
return this.beanFactory.getBean("dataSource", DataSource.class);
- }
- catch (RuntimeException ex) {
+ } catch (RuntimeException ex) {
return this.beanFactory.getBean(DataSource.class);
}
}
protected String[] getPackagesToScan() {
- List basePackages = AutoConfigurationUtils
- .getBasePackages(this.beanFactory);
- Assert.notEmpty(basePackages,
- "Unable to find JPA packages to scan, please define "
- + "a @ComponentScan annotation or disable JpaAutoConfiguration");
+ List basePackages = AutoConfigurationUtils.getBasePackages(this.beanFactory);
+ Assert.notEmpty(basePackages, "Unable to find JPA packages to scan, please define "
+ + "a @ComponentScan annotation or disable JpaAutoConfiguration");
return basePackages.toArray(new String[basePackages.size()]);
}
- protected void configure(
- LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
+ protected void configure(LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
}
@Override
diff --git a/spring-autoconfigure/src/test/java/org/springframework/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java b/spring-autoconfigure/src/test/java/org/springframework/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java
index f3a0ac4b726..70f8d0e7cae 100644
--- a/spring-autoconfigure/src/test/java/org/springframework/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java
+++ b/spring-autoconfigure/src/test/java/org/springframework/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java
@@ -16,21 +16,29 @@
package org.springframework.autoconfigure.orm.jpa;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
import javax.sql.DataSource;
+import org.junit.After;
import org.junit.Test;
import org.springframework.autoconfigure.ComponentScanDetectorConfiguration;
import org.springframework.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.autoconfigure.jdbc.EmbeddedDatabaseConfiguration;
-import org.springframework.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.autoconfigure.orm.jpa.test.City;
+import org.springframework.bootstrap.TestUtils;
+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 static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
+import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
+import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
/**
* Tests for {@link HibernateJpaAutoConfiguration}.
@@ -39,11 +47,18 @@ import static org.junit.Assert.assertTrue;
*/
public class HibernateJpaAutoConfigurationTests {
- private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ private ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
+
+ @After
+ public void close() {
+ if (context != null) {
+ context.close();
+ }
+ }
@Test
public void testEntityManagerCreated() throws Exception {
- this.context.register(ComponentScanDetectorConfiguration.class,
+ ((AnnotationConfigApplicationContext) this.context).register(ComponentScanDetectorConfiguration.class,
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class);
this.context.refresh();
@@ -53,17 +68,58 @@ public class HibernateJpaAutoConfigurationTests {
@Test
public void testDataSourceTransactionManagerNotCreated() throws Exception {
- this.context.register(ComponentScanDetectorConfiguration.class,
+ ((AnnotationConfigApplicationContext) this.context).register(ComponentScanDetectorConfiguration.class,
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
- DataSourceTransactionManagerAutoConfiguration.class,
- PropertyPlaceholderAutoConfiguration.class, TestConfiguration.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, this.context.getBeanNamesForType(OpenEntityManagerInViewInterceptor.class).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, this.context.getBeanNamesForType(OpenEntityManagerInViewInterceptor.class).length);
+ }
+
@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-bootstrap/pom.xml b/spring-bootstrap/pom.xml
index 29e3b1b099d..7492a23fdc5 100644
--- a/spring-bootstrap/pom.xml
+++ b/spring-bootstrap/pom.xml
@@ -99,6 +99,11 @@
jcl-over-slf4j
test
+
+ org.slf4j
+ slf4j-jdk14
+ test
+