From b6b386893e097da353bbcb5b8668e38409ff8a40 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 23 Aug 2011 09:04:20 +0200 Subject: [PATCH] DATADOC-90 - Fixed potential concurrency problem for PartTree based query creation. We now eagerly create CriteriaQuery and it's ParameterExpressions in QueryPreparer's constructor. Lazily doing so could let to exceptions accessing the ParameterExpressions in race conditions. --- .../repository/query/PartTreeJpaQuery.java | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java index cdb6bda3b..137c2578a 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java @@ -58,8 +58,10 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { this.tree = new PartTree(method.getName(), domainClass); this.parameters = method.getParameters(); - this.query = new QueryPreparer(); - this.countQuery = new CountQueryPreparer(); + this.query = + new QueryPreparer(parameters.potentiallySortsDynamically()); + this.countQuery = + new CountQueryPreparer(parameters.potentiallySortsDynamically()); } @@ -98,8 +100,17 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { */ private class QueryPreparer { - private CriteriaQuery query; - private JpaQueryCreator creator; + private final CriteriaQuery query; + private final List> expressions; + + + public QueryPreparer(boolean recreateQueries) { + + JpaQueryCreator creator = createCreator(); + this.query = recreateQueries ? null : creator.createQuery(); + this.expressions = + recreateQueries ? null : creator.getParameterExpressions(); + } /** @@ -110,16 +121,18 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { */ public Query createQuery(Object[] values) { - if (parameters.potentiallySortsDynamically() || query == null - || creator == null) { - creator = createCreator(); - query = creator.createQuery(getDynamicSort(values)); + CriteriaQuery criteriaQuery = query; + List> expressions = this.expressions; + + if (query == null) { + JpaQueryCreator creator = createCreator(); + criteriaQuery = creator.createQuery(getDynamicSort(values)); + expressions = creator.getParameterExpressions(); } - TypedQuery jpaQuery = getEntityManager().createQuery(query); - return invokeBinding( - getBinder(values, creator.getParameterExpressions()), - jpaQuery); + TypedQuery jpaQuery = + getEntityManager().createQuery(criteriaQuery); + return invokeBinding(getBinder(values, expressions), jpaQuery); } @@ -166,6 +179,12 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { */ private class CountQueryPreparer extends QueryPreparer { + public CountQueryPreparer(boolean recreateQueries) { + + super(recreateQueries); + } + + /* * (non-Javadoc) *