private static void PerformBeforeAssemble( ICacheAssembler[] returnTypes, ISessionImplementor session, IList cacheable) { if (returnTypes.Length == 1) { var returnType = returnTypes[0]; // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { returnType.BeforeAssemble(cacheable[i], session); } } else { // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { TypeHelper.BeforeAssemble((object[])cacheable[i], returnTypes, session); } } }
public IList Get(QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISet <string> spaces, ISessionImplementor session) { if (Log.IsDebugEnabled) { Log.DebugFormat("checking cached query results in region: '{0}'; {1}", _regionName, key); } var cacheable = (IList)_queryCache.Get(key); if (cacheable == null) { Log.DebugFormat("query results were not found in cache: {0}", key); return(null); } var timestamp = (long)cacheable[0]; if (Log.IsDebugEnabled) { Log.DebugFormat("Checking query spaces for up-to-dateness [{0}]", StringHelper.CollectionToString(spaces)); } if (!isNaturalKeyLookup && !IsUpToDate(spaces, timestamp)) { Log.DebugFormat("cached query results were not up to date for: {0}", key); return(null); } Log.DebugFormat("returning cached query results for: {0}", key); for (int i = 1; i < cacheable.Count; i++) { if (returnTypes.Length == 1 && !key.HasResultTransformer) { returnTypes[0].BeforeAssemble(cacheable[i], session); } else { TypeHelper.BeforeAssemble((object[])cacheable[i], returnTypes, session); } } IList result = new List <object>(cacheable.Count - 1); for (int i = 1; i < cacheable.Count; i++) { try { if (returnTypes.Length == 1 && !key.HasResultTransformer) { result.Add(returnTypes[0].Assemble(cacheable[i], session, null)); } else { result.Add(TypeHelper.Assemble((object[])cacheable[i], returnTypes, session, null)); } } catch (UnresolvableObjectException) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug("could not reassemble cached result set"); _queryCache.Remove(key); return(null); } throw; } } return(result); }
private IList GetResultFromCacheable( QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISessionImplementor session, IList cacheable) { Log.Debug("returning cached query results for: {0}", key); if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0) { returnTypes = GuessTypes(cacheable); } try { var result = new List <object>(cacheable.Count - 1); if (returnTypes.Length == 1) { var returnType = returnTypes[0]; // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { returnType.BeforeAssemble(cacheable[i], session); } for (var i = 1; i < cacheable.Count; i++) { result.Add(returnType.Assemble(cacheable[i], session, null)); } } else { var collectionIndexes = new Dictionary <int, ICollectionPersister>(); var nonCollectionTypeIndexes = new List <int>(); for (var i = 0; i < returnTypes.Length; i++) { if (returnTypes[i] is CollectionType collectionType) { collectionIndexes.Add(i, session.Factory.GetCollectionPersister(collectionType.Role)); } else { nonCollectionTypeIndexes.Add(i); } } // Skip first element, it is the timestamp for (var i = 1; i < cacheable.Count; i++) { TypeHelper.BeforeAssemble((object[])cacheable[i], returnTypes, session); } for (var i = 1; i < cacheable.Count; i++) { result.Add(TypeHelper.Assemble((object[])cacheable[i], returnTypes, nonCollectionTypeIndexes, session)); } // Initialization of the fetched collection must be done at the end in order to be able to batch fetch them // from the cache or database. The collections were already created in the previous for statement so we only // have to initialize them. if (collectionIndexes.Count > 0) { for (var i = 1; i < cacheable.Count; i++) { TypeHelper.InitializeCollections((object[])cacheable[i], (object[])result[i - 1], collectionIndexes, session); } } } return(result); } catch (UnresolvableObjectException ex) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug(ex, "could not reassemble cached result set"); // Handling a RemoveMany here does not look worth it, as this case short-circuits // the result-set. So a Many could only benefit batched queries, and only if many // of them are natural key lookup with an unresolvable object case. Cache.Remove(key); return(null); } throw; } }
private IList GetResultFromCacheable( QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISessionImplementor session, IList cacheable) { Log.Debug("returning cached query results for: {0}", key); if (key.ResultTransformer?.AutoDiscoverTypes == true && cacheable.Count > 0) { returnTypes = GuessTypes(cacheable); } try { var result = new List <object>(cacheable.Count - 1); if (returnTypes.Length == 1) { var returnType = returnTypes[0]; // Skip first element, it is the timestamp var rows = new List <object>(cacheable.Count - 1); for (var i = 1; i < cacheable.Count; i++) { rows.Add(cacheable[i]); } foreach (var row in rows) { returnType.BeforeAssemble(row, session); } foreach (var row in rows) { result.Add(returnType.Assemble(row, session, null)); } } else { // Skip first element, it is the timestamp var rows = new List <object[]>(cacheable.Count - 1); for (var i = 1; i < cacheable.Count; i++) { rows.Add((object[])cacheable[i]); } foreach (var row in rows) { TypeHelper.BeforeAssemble(row, returnTypes, session); } foreach (var row in rows) { result.Add(TypeHelper.Assemble(row, returnTypes, session, null)); } } return(result); } catch (UnresolvableObjectException ex) { if (isNaturalKeyLookup) { //TODO: not really completely correct, since // the UnresolvableObjectException could occur while resolving // associations, leaving the PC in an inconsistent state Log.Debug(ex, "could not reassemble cached result set"); // Handling a RemoveMany here does not look worth it, as this case short-circuits // the result-set. So a Many could only benefit batched queries, and only if many // of them are natural key lookup with an unresolvable object case. Cache.Remove(key); return(null); } throw; } }