DATACMNS-390 - Create defensive copy for persistent entities in AbstractMappingContext.

To prevent ConcurrentModificationExceptions when iterating over PersistentEntities while further entity types are potentially added to the MappingContext we now return a immutable defensive copy of the current entity set.
This commit is contained in:
Oliver Gierke
2013-11-04 11:29:31 +01:00
parent 62d5edf722
commit dc7a9a442e
2 changed files with 21 additions and 1 deletions

View File

@@ -122,7 +122,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
public Collection<E> getPersistentEntities() {
try {
read.lock();
return persistentEntities.values();
return Collections.unmodifiableSet(new HashSet<E>(persistentEntities.values()));
} finally {
read.unlock();
}

View File

@@ -21,6 +21,7 @@ import static org.mockito.Mockito.*;
import groovy.lang.MetaClass;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.junit.Before;
@@ -34,6 +35,7 @@ import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.mapping.model.BasicPersistentEntity;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
/**
@@ -171,6 +173,24 @@ public class AbstractMappingContextUnitTests {
assertThat(propertyEntity.getType(), is(equalTo((Class) Person.class)));
}
/**
* @see DATACMNS-390
*/
@Test
public void exposesCopyOfPersistentEntitiesToAvoidConcurrentModificationException() {
SampleMappingContext context = new SampleMappingContext();
context.getPersistentEntity(ClassTypeInformation.MAP);
Iterator<BasicPersistentEntity<Object, SamplePersistentProperty>> iterator = context.getPersistentEntities()
.iterator();
while (iterator.hasNext()) {
context.getPersistentEntity(ClassTypeInformation.SET);
iterator.next();
}
}
class Person {
String name;
}