From 9edf2e58065bf144bb7db4647e95ff52ee2e3bda 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 ConcurrentHashMap. We now use ConcurrentHashMap to store persistent properties of a PersistentEntity and to prevent eviction caused by GC activity. 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 | 2 +- .../mapping/model/BasicPersistentEntityUnitTests.java | 11 +++++++---- 2 files changed, 8 insertions(+), 5 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 6885e3835b..2063dc7aa2 100644 --- a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java +++ b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java @@ -104,7 +104,7 @@ public BasicPersistentEntity(TypeInformation information, @Nullable Comparato this.constructor = PreferredConstructorDiscoverer.discover(this); this.associations = comparator == null ? new HashSet<>() : new TreeSet<>(new AssociationComparator<>(comparator)); - this.propertyCache = new ConcurrentReferenceHashMap<>(); + this.propertyCache = new ConcurrentHashMap<>(); this.annotationCache = new ConcurrentReferenceHashMap<>(); this.propertyAnnotationCache = CollectionUtils.toMultiValueMap(new ConcurrentReferenceHashMap<>()); this.propertyAccessorFactory = BeanWrapperPropertyAccessorFactory.INSTANCE; 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 88672ea24d..baeee9fcf4 100755 --- a/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java @@ -138,24 +138,27 @@ public void considersComparatorForPropertyOrder() { 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); @@ -429,7 +432,7 @@ static class PersistableEntity implements Persistable { private final Long id = 42L; - /* + /* * (non-Javadoc) * @see org.springframework.data.domain.Persistable#getId() */ @@ -438,7 +441,7 @@ public Long getId() { return 4711L; } - /* + /* * (non-Javadoc) * @see org.springframework.data.domain.Persistable#isNew() */