Skip to content

Commit 7ad9b99

Browse files
NH-2319 - Fix plan retrieved from cache case. To be squashed.
1 parent cbf5067 commit 7ad9b99

File tree

3 files changed

+44
-36
lines changed

3 files changed

+44
-36
lines changed

src/NHibernate/Engine/Query/FilterQueryPlan.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,23 @@ namespace NHibernate.Engine.Query
1010
[Serializable]
1111
public class FilterQueryPlan : QueryExpressionPlan
1212
{
13-
private readonly string collectionRole;
14-
1513
public FilterQueryPlan(IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
1614
: base(queryExpression, collectionRole, shallow, enabledFilters, factory)
1715
{
18-
this.collectionRole = collectionRole;
16+
CollectionRole = collectionRole;
1917
}
2018

21-
public string CollectionRole
19+
protected FilterQueryPlan(FilterQueryPlan source, IQueryExpression expression)
20+
: base (source, expression)
21+
{
22+
CollectionRole = source.CollectionRole;
23+
}
24+
25+
public string CollectionRole { get; }
26+
27+
public override QueryExpressionPlan Copy(IQueryExpression expression)
2228
{
23-
get { return collectionRole; }
29+
return new FilterQueryPlan(this, expression);
2430
}
2531
}
26-
}
32+
}

src/NHibernate/Engine/Query/QueryExpressionPlan.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace NHibernate.Engine.Query
88
[Serializable]
99
public class QueryExpressionPlan : HQLQueryPlan, IQueryExpressionPlan
1010
{
11-
public IQueryExpression QueryExpression { get; private set; }
11+
public IQueryExpression QueryExpression { get; }
1212

1313
public QueryExpressionPlan(IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
1414
: this(queryExpression.Key, CreateTranslators(queryExpression, collectionRole, shallow, enabledFilters, factory))
@@ -27,7 +27,7 @@ protected QueryExpressionPlan(string key, IQueryTranslator[] translators)
2727
{
2828
}
2929

30-
private QueryExpressionPlan(HQLQueryPlan source, IQueryExpression expression)
30+
protected QueryExpressionPlan(HQLQueryPlan source, IQueryExpression expression)
3131
: base(source)
3232
{
3333
QueryExpression = expression;
@@ -38,9 +38,9 @@ protected static IQueryTranslator[] CreateTranslators(IQueryExpression queryExpr
3838
return factory.Settings.QueryTranslatorFactory.CreateQueryTranslators(queryExpression, collectionRole, shallow, enabledFilters, factory);
3939
}
4040

41-
public QueryExpressionPlan Copy(IQueryExpression expression)
41+
public virtual QueryExpressionPlan Copy(IQueryExpression expression)
4242
{
4343
return new QueryExpressionPlan(this, expression);
4444
}
4545
}
46-
}
46+
}

src/NHibernate/Engine/Query/QueryPlanCache.cs

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,30 @@ public IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bo
6767
{
6868
log.Debug("located HQL query plan in cache (" + queryExpression.Key + ")");
6969
}
70-
var planExpression = plan.QueryExpression as NhLinqExpression;
71-
var expression = queryExpression as NhLinqExpression;
72-
if (planExpression != null && expression != null)
73-
{
74-
//NH-3413
75-
//Here we have to use original expression.
76-
//In most cases NH do not translate expression in second time, but
77-
// for cases when we have list parameters in query, like @p1.Contains(...),
78-
// it does, and then it uses parameters from first try.
79-
//TODO: cache only required parts of QueryExpression
80-
81-
//NH-3436
82-
// We have to return new instance plan with it's own query expression
83-
// because other treads can override queryexpression of current plan during execution of query if we will use cached instance of plan
84-
expression.CopyExpressionTranslation(planExpression);
85-
plan = plan.Copy(expression);
86-
}
70+
plan = CopyIfRequired(plan, queryExpression);
71+
}
72+
73+
return plan;
74+
}
75+
76+
private static QueryExpressionPlan CopyIfRequired(QueryExpressionPlan plan, IQueryExpression queryExpression)
77+
{
78+
var planExpression = plan.QueryExpression as NhLinqExpression;
79+
var expression = queryExpression as NhLinqExpression;
80+
if (planExpression != null && expression != null)
81+
{
82+
//NH-3413
83+
//Here we have to use original expression.
84+
//In most cases NH do not translate expression in second time, but
85+
// for cases when we have list parameters in query, like @p1.Contains(...),
86+
// it does, and then it uses parameters from first try.
87+
//TODO: cache only required parts of QueryExpression
88+
89+
//NH-3436
90+
// We have to return new instance plan with it's own query expression
91+
// because other treads can override queryexpression of current plan during execution of query if we will use cached instance of plan
92+
expression.CopyExpressionTranslation(planExpression);
93+
plan = plan.Copy(expression);
8794
}
8895

8996
return plan;
@@ -97,23 +104,18 @@ public IQueryExpressionPlan GetFilterQueryPlan(string filterString, string colle
97104
public IQueryExpressionPlan GetFilterQueryPlan(IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> enabledFilters)
98105
{
99106
var key = new FilterQueryPlanKey(queryExpression.Key, collectionRole, shallow, enabledFilters);
100-
var plan = (IQueryExpressionPlan) planCache[key];
107+
var plan = (QueryExpressionPlan) planCache[key];
101108

102109
if (plan == null)
103110
{
104-
if (log.IsDebugEnabled)
105-
{
106-
log.Debug(string.Format("unable to locate collection-filter query plan in cache; generating ({0} : {1})", collectionRole, queryExpression.Key));
107-
}
111+
log.DebugFormat("unable to locate collection-filter query plan in cache; generating ({0} : {1})", collectionRole, queryExpression.Key);
108112
plan = new FilterQueryPlan(queryExpression, collectionRole, shallow, enabledFilters, factory);
109113
planCache.Put(key, plan);
110114
}
111115
else
112116
{
113-
if (log.IsDebugEnabled)
114-
{
115-
log.Debug(string.Format("located collection-filter query plan in cache ({0} : {1})", collectionRole, queryExpression.Key));
116-
}
117+
log.DebugFormat("located collection-filter query plan in cache ({0} : {1})", collectionRole, queryExpression.Key);
118+
plan = CopyIfRequired(plan, queryExpression);
117119
}
118120

119121
return plan;

0 commit comments

Comments
 (0)