();
+ names.addAll(asList(beanNamesForTypeIncludingAncestors(beanFactory, EntityManagerFactory.class, true, false)));
+
+ for (String factoryBeanName : beanNamesForTypeIncludingAncestors(beanFactory,
+ AbstractEntityManagerFactoryBean.class, true, false)) {
+ names.add(factoryBeanName.substring(1));
+ }
+
+ return names;
+ }
}
diff --git a/src/main/java/org/springframework/data/jpa/domain/support/AuditingEntityListener.java b/src/main/java/org/springframework/data/jpa/domain/support/AuditingEntityListener.java
index 148f825bc..4bd7dc11e 100644
--- a/src/main/java/org/springframework/data/jpa/domain/support/AuditingEntityListener.java
+++ b/src/main/java/org/springframework/data/jpa/domain/support/AuditingEntityListener.java
@@ -19,7 +19,6 @@ import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import org.springframework.beans.factory.annotation.Configurable;
-import org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect;
import org.springframework.data.auditing.AuditingHandler;
import org.springframework.data.domain.Auditable;
@@ -40,6 +39,14 @@ import org.springframework.data.domain.Auditable;
* After that it's just a matter of activating auditing in your Spring config:
*
*
+ * @Configuration
+ * @EnableJpaAuditing
+ * class ApplicationConfig {
+ *
+ * }
+ *
+ *
+ *
* <jpa:auditing auditor-aware-ref="yourAuditorAwarebean" />
*
*
@@ -52,14 +59,8 @@ public class AuditingEntityListener {
private AuditingHandler handler;
/**
- * Creates an {@link AuditingEntityListener} that auto-wires itself according to the appropriate Spring bean
- * configuration.
- */
- public AuditingEntityListener() {
- AnnotationBeanConfigurerAspect.aspectOf().configureBean(this);
- }
-
- /**
+ * Configures the {@link AuditingHandler} to be used to set the current auditor on the domain types touched.
+ *
* @param auditingHandler the handler to set
*/
public void setAuditingHandler(AuditingHandler auditingHandler) {
diff --git a/src/main/java/org/springframework/data/jpa/repository/config/EnableJpaAuditing.java b/src/main/java/org/springframework/data/jpa/repository/config/EnableJpaAuditing.java
index 68b5b003d..91727a3ac 100644
--- a/src/main/java/org/springframework/data/jpa/repository/config/EnableJpaAuditing.java
+++ b/src/main/java/org/springframework/data/jpa/repository/config/EnableJpaAuditing.java
@@ -22,13 +22,16 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.joda.time.DateTime;
import org.springframework.context.annotation.Import;
import org.springframework.data.auditing.DateTimeProvider;
+import org.springframework.data.domain.AuditorAware;
/**
* Annotation to enable auditing in JPA via annotation configuration.
*
* @author Thomas Darimont
+ * @author Oliver Gierke
*/
@Inherited
@Documented
@@ -38,23 +41,31 @@ import org.springframework.data.auditing.DateTimeProvider;
public @interface EnableJpaAuditing {
/**
- * @return References a bean of type AuditorAware to represent the current principal.
+ * Configures the {@link AuditorAware} bean to be used to lookup the current principal.
+ *
+ * @return
*/
String auditorAwareRef() default "";
/**
- * @return Configures whether the creation and modification dates are set and defaults to {@literal true}.
+ * Configures whether the creation and modification dates are set. Defaults to {@literal true}.
+ *
+ * @return
*/
boolean setDates() default true;
/**
- * @return Configures whether the entity shall be marked as modified on creation and defaults to {@literal true}.
+ * Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}.
+ *
+ * @return
*/
boolean modifyOnCreate() default true;
/**
- * @return Configures a {@link DateTimeProvider} that allows customizing which DateTime shall be used for setting
- * creation and modification dates.
+ * Configures a {@link DateTimeProvider} bean name that allows customizing the {@link DateTime} to be used for setting
+ * creation and modification dates.
+ *
+ * @return
*/
String dateTimeProviderRef() default "";
}
diff --git a/src/main/java/org/springframework/data/jpa/repository/config/JpaAuditingRegistrar.java b/src/main/java/org/springframework/data/jpa/repository/config/JpaAuditingRegistrar.java
index b2edc8f36..796b8eb84 100644
--- a/src/main/java/org/springframework/data/jpa/repository/config/JpaAuditingRegistrar.java
+++ b/src/main/java/org/springframework/data/jpa/repository/config/JpaAuditingRegistrar.java
@@ -15,6 +15,8 @@
*/
package org.springframework.data.jpa.repository.config;
+import static org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessor.*;
+
import java.lang.annotation.Annotation;
import org.springframework.beans.factory.BeanDefinitionStoreException;
@@ -39,13 +41,10 @@ import org.springframework.util.ClassUtils;
*/
class JpaAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
- /**
- * The bean name of the internally managed bean configurer aspect.
- */
- private static final String BEAN_CONFIGURER_ASPECT_BEAN_NAME = "org.springframework.context.config.internalBeanConfigurerAspect";
private static final String BEAN_CONFIGURER_ASPECT_CLASS_NAME = "org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect";
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
*/
@Override
@@ -53,7 +52,8 @@ class JpaAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
return EnableJpaAuditing.class;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
*/
@Override
@@ -68,7 +68,8 @@ class JpaAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
.getRawBeanDefinition(), AuditingBeanFactoryPostProcessor.class.getName(), registry);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry)
*/
@Override
@@ -86,7 +87,7 @@ class JpaAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
*/
private void registerBeanConfigurerAspectIfNecessary(BeanDefinitionRegistry registry) {
- if (registry.containsBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME)) {
+ if (registry.containsBeanDefinition(BEAN_CONFIGURER_ASPECT_CLASS_NAME)) {
return;
}
diff --git a/src/test/java/org/springframework/data/jpa/domain/support/AnnotationAuditingBeanFactoryPostProcessorUnitTests.java b/src/test/java/org/springframework/data/jpa/domain/support/AnnotationAuditingBeanFactoryPostProcessorUnitTests.java
new file mode 100644
index 000000000..e01713fe4
--- /dev/null
+++ b/src/test/java/org/springframework/data/jpa/domain/support/AnnotationAuditingBeanFactoryPostProcessorUnitTests.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 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.data.jpa.domain.support;
+
+import static org.mockito.Mockito.*;
+
+import javax.persistence.EntityManagerFactory;
+
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ConfigurationClassPostProcessor;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+
+/**
+ * Unit tests to check that the {@link AuditingBeanFactoryPostProcessor} does its job for annotation based
+ * configuration.
+ *
+ * @author Oliver Gierke
+ */
+public class AnnotationAuditingBeanFactoryPostProcessorUnitTests extends AuditingBeanFactoryPostProcessorUnitTests {
+
+ @Configuration
+ @EnableJpaAuditing
+ static class TestConfig {
+
+ @Bean
+ public EntityManagerFactory entityManagerFactory() {
+ return mock(EntityManagerFactory.class);
+ }
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
+ return mock(LocalContainerEntityManagerFactoryBean.class);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessorUnitTests#getBeanFactory()
+ */
+ @Override
+ protected DefaultListableBeanFactory getBeanFactory() {
+
+ DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
+ beanFactory.registerBeanDefinition("testConfig", new RootBeanDefinition(TestConfig.class));
+
+ ConfigurationClassPostProcessor processor = new ConfigurationClassPostProcessor();
+ processor.postProcessBeanDefinitionRegistry(beanFactory);
+
+ return beanFactory;
+ }
+}
diff --git a/src/test/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessorUnitTests.java b/src/test/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessorUnitTests.java
index 8d8cef7a0..43d5a268c 100644
--- a/src/test/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessorUnitTests.java
+++ b/src/test/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessorUnitTests.java
@@ -15,11 +15,14 @@
*/
package org.springframework.data.jpa.domain.support;
-import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
+import javax.persistence.EntityManagerFactory;
+
import org.junit.Before;
import org.junit.Test;
+import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
@@ -38,18 +41,23 @@ public class AuditingBeanFactoryPostProcessorUnitTests {
@Before
public void setUp() {
- beanFactory = new DefaultListableBeanFactory();
- XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
- reader.loadBeanDefinitions(new ClassPathResource("auditing/" + getConfigFile()));
-
- processor = new AuditingBeanFactoryPostProcessor();
+ this.beanFactory = getBeanFactory();
+ this.processor = new AuditingBeanFactoryPostProcessor();
}
protected String getConfigFile() {
-
return "auditing-bfpp-context.xml";
}
+ protected DefaultListableBeanFactory getBeanFactory() {
+
+ DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
+ XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
+ reader.loadBeanDefinitions(new ClassPathResource("auditing/" + getConfigFile()));
+
+ return beanFactory;
+ }
+
@Test
public void beanConfigurerAspectShouldBeConfiguredAfterPostProcessing() throws Exception {
@@ -57,4 +65,30 @@ public class AuditingBeanFactoryPostProcessorUnitTests {
assertThat(beanFactory.isBeanNameInUse(AuditingBeanFactoryPostProcessor.BEAN_CONFIGURER_ASPECT_BEAN_NAME), is(true));
}
+
+ /**
+ * @see DATAJPA-265
+ */
+ @Test(expected = IllegalStateException.class)
+ public void rejectsConfigurationWithoutSpringConfigured() {
+ processor.postProcessBeanFactory(new DefaultListableBeanFactory());
+ }
+
+ /**
+ * @see DATAJPA-265
+ */
+ @Test
+ public void setsDependsOnOnEntityManagerFactory() {
+
+ processor.postProcessBeanFactory(beanFactory);
+
+ String[] emfDefinitionNames = beanFactory.getBeanNamesForType(EntityManagerFactory.class);
+
+ for (String emfDefinitionName : emfDefinitionNames) {
+ BeanDefinition emfDefinition = beanFactory.getBeanDefinition(emfDefinitionName);
+ assertThat(emfDefinition, is(notNullValue()));
+ assertThat(emfDefinition.getDependsOn(),
+ is(arrayContaining(AuditingBeanFactoryPostProcessor.BEAN_CONFIGURER_ASPECT_BEAN_NAME)));
+ }
+ }
}
diff --git a/src/test/java/org/springframework/data/jpa/repository/config/AbstractAuditingViaJavaConfigRepositoriesTests.java b/src/test/java/org/springframework/data/jpa/repository/config/AbstractAuditingViaJavaConfigRepositoriesTests.java
index 787e1f423..37c57d92f 100644
--- a/src/test/java/org/springframework/data/jpa/repository/config/AbstractAuditingViaJavaConfigRepositoriesTests.java
+++ b/src/test/java/org/springframework/data/jpa/repository/config/AbstractAuditingViaJavaConfigRepositoriesTests.java
@@ -38,6 +38,7 @@ import org.springframework.transaction.annotation.Transactional;
* Integration tests for auditing via Java config.
*
* @author Thomas Darimont
+ * @author Oliver Gierke
*/
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@@ -54,10 +55,11 @@ public abstract class AbstractAuditingViaJavaConfigRepositoriesTests {
@Before
public void setup() {
+
AuditableUser auditor = new AuditableUser(null);
auditor.setFirstname("auditor");
- this.auditor = this.auditableUserRepository.save(auditor);
+ this.auditor = this.auditableUserRepository.save(auditor);
doReturn(this.auditor).when(this.auditorAware).getCurrentAuditor();
}
@@ -67,7 +69,6 @@ public abstract class AbstractAuditingViaJavaConfigRepositoriesTests {
}
@Test
- @Transactional
public void basicAuditing() throws Exception {
AuditableUser user = new AuditableUser(null);
diff --git a/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java b/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java
index 1e89e75ac..ede0713ee 100644
--- a/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java
+++ b/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java
@@ -76,7 +76,7 @@ public class AuditingBeanDefinitionParserTests {
ShadowingClassLoader scl = new ShadowingClassLoader(getClass().getClassLoader());
scl.excludeClass(AuditingBeanDefinitionParser.AUDITING_ENTITY_LISTENER_CLASS_NAME);
- DefaultListableBeanFactory factory = loadFactoryFrom("auditing/auditing-namespace-context.xml", scl);
+ loadFactoryFrom("auditing/auditing-namespace-context.xml", scl);
}
private void assertSetDatesIsSetTo(String configFile, String value) {
diff --git a/src/test/java/org/springframework/data/jpa/repository/config/DefaultAuditingViaJavaConfigRepositoriesTests.java b/src/test/java/org/springframework/data/jpa/repository/config/DefaultAuditingViaJavaConfigRepositoriesTests.java
index 870f10219..c38fe4c7a 100644
--- a/src/test/java/org/springframework/data/jpa/repository/config/DefaultAuditingViaJavaConfigRepositoriesTests.java
+++ b/src/test/java/org/springframework/data/jpa/repository/config/DefaultAuditingViaJavaConfigRepositoriesTests.java
@@ -28,6 +28,7 @@ import org.springframework.test.context.ContextConfiguration;
* Integration tests for auditing via Java config with default configuration.
*
* @author Thomas Darimont
+ * @author Oliver Gierke
*/
@ContextConfiguration
public class DefaultAuditingViaJavaConfigRepositoriesTests extends AbstractAuditingViaJavaConfigRepositoriesTests {
@@ -38,6 +39,7 @@ public class DefaultAuditingViaJavaConfigRepositoriesTests extends AbstractAudit
static class Config {
@Bean
+ @SuppressWarnings("unchecked")
public AuditorAware auditorProvider() {
return mock(AuditorAware.class);
}
diff --git a/src/test/java/org/springframework/data/jpa/repository/config/ExplicitAuditingViaJavaConfigRepositoriesTests.java b/src/test/java/org/springframework/data/jpa/repository/config/ExplicitAuditingViaJavaConfigRepositoriesTests.java
index 7ffc2b409..e95e28a6e 100644
--- a/src/test/java/org/springframework/data/jpa/repository/config/ExplicitAuditingViaJavaConfigRepositoriesTests.java
+++ b/src/test/java/org/springframework/data/jpa/repository/config/ExplicitAuditingViaJavaConfigRepositoriesTests.java
@@ -28,8 +28,8 @@ import org.springframework.test.context.ContextConfiguration;
* Integration tests for auditing via Java config with explicit configuration.
*
* @author Thomas Darimont
+ * @author Oliver Gierke
*/
-
@ContextConfiguration
public class ExplicitAuditingViaJavaConfigRepositoriesTests extends AbstractAuditingViaJavaConfigRepositoriesTests {
@@ -39,6 +39,7 @@ public class ExplicitAuditingViaJavaConfigRepositoriesTests extends AbstractAudi
static class Config {
@Bean
+ @SuppressWarnings("unchecked")
public AuditorAware auditorProvider() {
return mock(AuditorAware.class);
}