Skip to content

Commit 1d4c96e

Browse files
committed
DATAJPA-1446 - Clear JpaMetamodel CACHE when application context is closed.
1 parent 54fe0ae commit 1d4c96e

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

src/main/java/org/springframework/data/jpa/repository/config/JpaMetamodelMappingContextFactoryBean.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.context.ApplicationContext;
3232
import org.springframework.context.ApplicationContextAware;
3333
import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext;
34+
import org.springframework.data.jpa.util.JpaMetamodel;
3435
import org.springframework.data.util.StreamUtils;
3536
import org.springframework.lang.Nullable;
3637

@@ -39,6 +40,7 @@
3940
*
4041
* @author Oliver Gierke
4142
* @author Mark Paluch
43+
* @author Sylvère Richard
4244
* @since 1.6
4345
*/
4446
class JpaMetamodelMappingContextFactoryBean extends AbstractFactoryBean<JpaMetamodelMappingContext>
@@ -66,6 +68,11 @@ public Class<?> getObjectType() {
6668
return JpaMetamodelMappingContext.class;
6769
}
6870

71+
@Override
72+
protected void destroyInstance(JpaMetamodelMappingContext instance) throws Exception {
73+
JpaMetamodel.clearCache();
74+
}
75+
6976
/*
7077
* (non-Javadoc)
7178
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()

src/main/java/org/springframework/data/jpa/util/JpaMetamodel.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
package org.springframework.data.jpa.util;
1717

1818
import java.util.Collection;
19-
import java.util.HashMap;
2019
import java.util.Map;
2120
import java.util.Optional;
21+
import java.util.concurrent.ConcurrentHashMap;
2222

2323
import javax.persistence.metamodel.EntityType;
2424
import javax.persistence.metamodel.ManagedType;
@@ -34,10 +34,11 @@
3434
*
3535
* @author Oliver Gierke
3636
* @author Mark Paluch
37+
* @author Sylvère Richard
3738
*/
3839
public class JpaMetamodel {
3940

40-
private static final Map<Metamodel, JpaMetamodel> CACHE = new HashMap<>(4);
41+
private static final Map<Metamodel, JpaMetamodel> CACHE = new ConcurrentHashMap<>(4);
4142

4243
private final Metamodel metamodel;
4344

@@ -63,6 +64,10 @@ public static JpaMetamodel of(Metamodel metamodel) {
6364
return CACHE.computeIfAbsent(metamodel, JpaMetamodel::new);
6465
}
6566

67+
public static void clearCache() {
68+
CACHE.clear();
69+
}
70+
6671
/**
6772
* Returns whether the given type is managed by the backing JPA {@link Metamodel}.
6873
*
@@ -78,7 +83,7 @@ public boolean isJpaManaged(Class<?> type) {
7883

7984
/**
8085
* Returns whether the attribute of given name and type is the single identifier attribute of the given entity.
81-
*
86+
*
8287
* @param entity must not be {@literal null}.
8388
* @param name must not be {@literal null}.
8489
* @param attributeType must not be {@literal null}.
@@ -98,7 +103,7 @@ public boolean isSingleIdAttribute(Class<?> entity, String name, Class<?> attrib
98103
/**
99104
* Returns the {@link SingularAttribute} representing the identifier of the given {@link EntityType} if it contains a
100105
* singular one.
101-
*
106+
*
102107
* @param entityType must not be {@literal null}.
103108
* @return
104109
*/

src/test/java/org/springframework/data/jpa/util/JpaMetamodelUnitTests.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@
3030

3131
/**
3232
* Unit tests for {@link JpaMetamodel}.
33-
*
33+
*
3434
* @author Oliver Gierke
35+
* @author Sylvère Richard
3536
*/
3637
@RunWith(MockitoJUnitRunner.class)
3738
public class JpaMetamodelUnitTests {
@@ -47,4 +48,13 @@ public void skipsEntityTypesWithoutJavaTypeForIdentifierLookup() {
4748

4849
assertThat(JpaMetamodel.of(metamodel).isSingleIdAttribute(Object.class, "id", Object.class)).isFalse();
4950
}
51+
52+
@Test //DATAJPA-1446
53+
public void cacheIsEffectiveUnlessCleared() {
54+
JpaMetamodel model1 = JpaMetamodel.of(metamodel);
55+
assertThat(model1).isEqualTo(JpaMetamodel.of(metamodel));
56+
57+
JpaMetamodel.clearCache();
58+
assertThat(model1).isNotEqualTo(JpaMetamodel.of(metamodel));
59+
}
5060
}

0 commit comments

Comments
 (0)