From a85b4f3da9c86fff0d58b1b85fb68baf7a0e328b Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 6 Aug 2018 09:53:22 +0200 Subject: [PATCH] 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. --- .../data/mapping/model/BasicPersistentEntity.java | 7 ++++--- .../mapping/model/BasicPersistentEntityUnitTests.java | 11 +++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java index 1899abe91..7395f3d17 100644 --- a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java +++ b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java @@ -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> 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())); } diff --git a/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java b/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java index 615b49671..751e6eb26 100755 --- a/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java @@ -126,24 +126,27 @@ public class BasicPersistentEntityUnitTests> { assertThat(entity.getPersistentProperty("ssn")).isEqualTo(iterator.next()); } - @Test // DATACMNS-186 + @Test // DATACMNS-18, DATACMNS-1364 public void addingAndIdPropertySetsIdPropertyInternally() { MutablePersistentEntity 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 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> { private final Long id = 42L; - /* + /* * (non-Javadoc) * @see org.springframework.data.domain.Persistable#getId() */ @@ -340,7 +343,7 @@ public class BasicPersistentEntityUnitTests> { return 4711L; } - /* + /* * (non-Javadoc) * @see org.springframework.data.domain.Persistable#isNew() */