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.
This commit is contained in:
Oliver Gierke
2011-08-23 09:04:20 +02:00
parent 0144be5b16
commit b6b386893e

View File

@@ -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<ParameterExpression<?>> 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<ParameterExpression<?>> 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)
*