DATACMNS-1364 - Store persistent properties in HashMap.

We now use HashMap to store persistent properties of a PersistentEntity. An entity is built in a single thread so no concurrent modification happens. Concurrent reads may happen during entity usage which is fine as the PersistentEntity is not changed anymore. Previously, we used ConcurrentReferenceHashMap defaulting to soft references. Soft references can be cleared at the discretion of the GC in response to memory demand. So a default ConcurrentReferenceHashMap is memory-sensitive and acts like a cache with memory-based eviction rules.

Persistent properties are not subject to be cached but elements of a PersistentEntity and cannot be recovered once cleared.

Original pull request: #304.
This commit is contained in:
Mark Paluch
2018-08-06 09:53:22 +02:00
parent b80f5c6714
commit a85b4f3da9
2 changed files with 11 additions and 7 deletions

View File

@@ -31,7 +31,8 @@ import org.springframework.data.util.Lazy;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
@@ -95,8 +96,8 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
this.associations = comparator == null ? new HashSet<>() : new TreeSet<>(new AssociationComparator<>(comparator));
this.propertyCache = new HashMap<>();
this.annotationCache = new HashMap<>();
this.propertyAnnotationCache = new LinkedMultiValueMap<>();
this.annotationCache = new ConcurrentReferenceHashMap<>();
this.propertyAnnotationCache = CollectionUtils.toMultiValueMap(new ConcurrentReferenceHashMap<>());
this.propertyAccessorFactory = BeanWrapperPropertyAccessorFactory.INSTANCE;
this.typeAlias = Lazy.of(() -> getAliasFromAnnotation(getType()));
}

View File

@@ -126,24 +126,27 @@ public class BasicPersistentEntityUnitTests<T extends PersistentProperty<T>> {
assertThat(entity.getPersistentProperty("ssn")).isEqualTo(iterator.next());
}
@Test // DATACMNS-186
@Test // DATACMNS-18, DATACMNS-1364
public void addingAndIdPropertySetsIdPropertyInternally() {
MutablePersistentEntity<Person, T> entity = createEntity(Person.class);
assertThat(entity.getIdProperty()).isNull();
when(property.getName()).thenReturn("id");
when(property.isIdProperty()).thenReturn(true);
entity.addPersistentProperty(property);
assertThat(entity.getIdProperty()).isEqualTo(property);
}
@Test // DATACMNS-186
@Test // DATACMNS-186, DATACMNS-1364
public void rejectsIdPropertyIfAlreadySet() {
MutablePersistentEntity<Person, T> entity = createEntity(Person.class);
when(property.getName()).thenReturn("id");
when(property.isIdProperty()).thenReturn(true);
when(anotherProperty.isIdProperty()).thenReturn(true);
when(anotherProperty.getName()).thenReturn("another");
entity.addPersistentProperty(property);
exception.expect(MappingException.class);
@@ -331,7 +334,7 @@ public class BasicPersistentEntityUnitTests<T extends PersistentProperty<T>> {
private final Long id = 42L;
/*
/*
* (non-Javadoc)
* @see org.springframework.data.domain.Persistable#getId()
*/
@@ -340,7 +343,7 @@ public class BasicPersistentEntityUnitTests<T extends PersistentProperty<T>> {
return 4711L;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.domain.Persistable#isNew()
*/