From b483cbc29a8b5de4d4ad3620a0ec15fe33c55acd Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 4 Jun 2012 12:24:10 +0200 Subject: [PATCH] DATACMNS-179 - Defer adding initial entity set to AbstractMappingContext. So far the domain classes to be added to the mapping context initially were added in afterPropertiesSet() of InitializingBean. This had the drawback that although the MappingContext is already set up properly the actual listeners of the events fired (e.g. index creating ones) might not have been set up properly. We list to the ContextRefreshedEvent indicating the entire ApplicationContext being set up completely. Thus all infrastructure components are set up properly and the timing issues doesn't exist anymore. --- .../context/AbstractMappingContext.java | 48 ++++++++++++++++--- ...gurableTypeInformationMapperUnitTests.java | 15 +++++- .../data/mapping/MappingMetadataTests.java | 4 +- .../AbstractMappingContextUnitTests.java | 26 +++++++++- 4 files changed, 83 insertions(+), 10 deletions(-) diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java index 736edd374..02d34b52c 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 by the original author(s). + * Copyright 2011-2012 by the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,9 +34,14 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PropertyPath; @@ -63,7 +68,8 @@ import org.springframework.validation.Validator; * @author Oliver Gierke */ public abstract class AbstractMappingContext, P extends PersistentProperty

> - implements MappingContext, InitializingBean, ApplicationEventPublisherAware { + implements MappingContext, InitializingBean, ApplicationEventPublisherAware, ApplicationContextAware, + ApplicationListener { private static final Set UNMAPPED_FIELDS = new HashSet(Arrays.asList("class", "this$0")); @@ -71,6 +77,7 @@ public abstract class AbstractMappingContext> validators = new ConcurrentHashMap>(); private ApplicationEventPublisher applicationEventPublisher; + private ApplicationContext applicationContext; private Set> initialEntitySet = new HashSet>(); private boolean strict = false; private SimpleTypeHolder simpleTypeHolder = new SimpleTypeHolder(); @@ -79,14 +86,25 @@ public abstract class AbstractMappingContext initialEntity : initialEntitySet) { addPersistentEntity(initialEntity); } diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java index 775482706..25f82770d 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -26,6 +26,11 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.PersistentProperty; @@ -42,9 +47,12 @@ import org.springframework.data.util.TypeInformation; * * @author Oliver Gierke */ +@RunWith(MockitoJUnitRunner.class) public class ConfigurableTypeInformationMapperUnitTests> { ConfigurableTypeInformationMapper mapper; + @Mock + ApplicationContext context; @Before public void setUp() { @@ -93,8 +101,11 @@ public class ConfigurableTypeInformationMapperUnitTests(this, null); } } -} \ No newline at end of file +} diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java index 06b4811d6..c54d378bb 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java @@ -1,13 +1,19 @@ package org.springframework.data.mapping.context; -import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import static org.mockito.Mockito.*; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; +import java.util.Collections; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.model.AbstractPersistentProperty; @@ -54,6 +60,24 @@ public class AbstractMappingContextUnitTests { context.getPersistentEntity(Unsupported.class); } + @Test + @SuppressWarnings("deprecation") + public void registersEntitiesOnContextRefreshedEvent() { + + ApplicationContext context = mock(ApplicationContext.class); + + DummyMappingContext mappingContext = new DummyMappingContext(); + mappingContext.setInitialEntitySet(Collections.singleton(Person.class)); + mappingContext.setApplicationContext(context); + mappingContext.setApplicationEventPublisher(context); + + mappingContext.afterPropertiesSet(); + verify(context, times(0)).publishEvent(Mockito.any(ApplicationEvent.class)); + + mappingContext.onApplicationEvent(new ContextRefreshedEvent(context)); + verify(context, times(1)).publishEvent(Mockito.any(ApplicationEvent.class)); + } + class Person { String name; }