Yohei Iwano
unread,Sep 5, 2011, 5:19:19 AM9/5/11Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to nhusers
I'm sorry for my poor English. But this happens in our system too.
At first, let me explain my understanding.
When I query linq contains collection parameter like this
from x in session.Query<SomeEntity> where
collectionParam.Contains(x.Col1) select x
It will process like this
1. Retrieve NhLinqExpression Query Plan from QueryPlanCache
2. Retrieve ExpandedQueryExpression Query Plan from QueryPlanCache
but if the collection parameter contains only one value(like "var
collectionParam = new int[] {100}").
It will process like this
1. Retrieve NhLinqExpression Query Plan from QueryPlanCache
2. Retrieve NhLinqExpression(not ExpandedQueryExpression!) Query Plan
from QueryPlanCache
this happens because of problem in creation of "query plan cache key".
When the collection parameter contains only one value,
NhLinqExpression and ExpandedQueryExpression both make same query plan
cache key.
(see ExpressionQueryImpl.ExpandParameters method)
Normally, this process works fine. But if the GC occurs between 1 and
2, and the NhLinqExpression objects are collected,
ExpandedQueryExpression(which is the same query plan cache key as
NhLinqExpression) is now going to cache.
In this time, softReferenceCache object in the SoftLimitMRUCache is
poisoned. And next time you try to execute linq, InvalidCastException
occurs...
I'm caching SessionFactory object in static field, and reuse it
between all threads/requests. The pollution of QueryPlanCache is
really serious problem...
(Additionally, I'm using ThreadStaticSessionContext to share Session
object between application layers. So I cannot recreate SessionFactory
object easily...)
Yohei