DATAJPA-620 - Avoid potential infinite loop in CrudMethodMetadataPostProcessor.

We now use a ConcurrentHashMap for the metadata cache. Previously we just used an plain HashMap in a potential concurrent read / write situation which could lead to an infinite loop on put.

Original pull request: #111.
This commit is contained in:
Thomas Darimont
2014-10-30 09:39:24 +01:00
committed by Oliver Gierke
parent be0fcad483
commit 7210a5c255

View File

@@ -19,6 +19,8 @@ import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.persistence.LockModeType;
import javax.persistence.QueryHint;
@@ -81,12 +83,13 @@ enum CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor {
*
* @see DefaultCrudMethodMetadata
* @author Oliver Gierke
* @author Thomas Darimont
*/
static enum CrudMethodMetadataPopulatingMethodIntercceptor implements MethodInterceptor {
INSTANCE;
private final Map<Method, CrudMethodMetadata> metadataCache = new HashMap<Method, CrudMethodMetadata>();
private final ConcurrentMap<Method, CrudMethodMetadata> metadataCache = new ConcurrentHashMap<Method, CrudMethodMetadata>();
/*
* (non-Javadoc)
@@ -104,8 +107,13 @@ enum CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor {
CrudMethodMetadata methodMetadata = metadataCache.get(method);
if (methodMetadata == null) {
methodMetadata = new DefaultCrudMethodMetadata(method);
metadataCache.put(method, methodMetadata);
CrudMethodMetadata tmp = metadataCache.putIfAbsent(method, methodMetadata);
if (tmp != null) {
metadata = tmp;
}
}
TransactionSynchronizationManager.bindResource(method, methodMetadata);