diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java index db6697a9d..287b39738 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java @@ -450,7 +450,7 @@ public final class JpqlQueryBuilder { /** * Select a single attribute. * - * @param name + * @param path * @return */ default Select select(JpqlQueryBuilder.PathExpression path) { diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java index dfde858df..e5107ee7c 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java @@ -279,12 +279,8 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { protected JpqlQueryCreator createCreator(Sort sort, JpaParametersParameterAccessor accessor) { - JpqlQueryCreator jpqlQueryCreator; - synchronized (cache) { - jpqlQueryCreator = cache.get(sort, accessor); // this caching thingy is broken due to IS NULL rendering for - // simple properties - } - + JpqlQueryCreator jpqlQueryCreator = cache.get(sort, accessor); // this caching thingy is broken due to IS NULL + // rendering for if (jpqlQueryCreator != null) { return jpqlQueryCreator; } @@ -307,9 +303,7 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { return creator; } - synchronized (cache) { - cache.put(sort, accessor, creator); - } + cache.put(sort, accessor, creator); return creator; } @@ -377,13 +371,12 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { */ private class CountQueryPreparer extends QueryPreparer { - private volatile JpqlQueryCreator cached; + private final PartTreeQueryCache cache = new PartTreeQueryCache(); @Override protected JpqlQueryCreator createCreator(Sort sort, JpaParametersParameterAccessor accessor) { - JpqlQueryCreator cached = this.cached; - + JpqlQueryCreator cached = cache.get(Sort.unsorted(), accessor); if (cached != null) { return cached; } @@ -393,7 +386,9 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { getQueryMethod().getResultProcessor().getReturnedType(), provider, templates, em); if (!accessor.getParameters().hasDynamicProjection()) { - return this.cached = new CacheableJpqlCountQueryCreator(creator); + cached = new CacheableJpqlCountQueryCreator(creator); + cache.put(Sort.unsorted(), accessor, cached); + return cached; } return creator; diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeQueryCache.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeQueryCache.java index 51183f4c6..59d30c915 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeQueryCache.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeQueryCache.java @@ -16,6 +16,7 @@ package org.springframework.data.jpa.repository.query; import java.util.BitSet; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; @@ -31,12 +32,12 @@ import org.springframework.util.ObjectUtils; */ class PartTreeQueryCache { - private final Map cache = new LinkedHashMap<>() { + private final Map cache = Collections.synchronizedMap(new LinkedHashMap<>() { @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > 256; } - }; + }); @Nullable JpqlQueryCreator get(Sort sort, JpaParametersParameterAccessor accessor) {