whimsical82
whimsical82

Reputation: 25

How to skip second level cache in query?

I use entity cache (second level cache) for an object. Now, in one specific query (I use OueryOver) I need to sidestep the second level cache. I have tried to omit the "Cacheable" attribute in my query but the query is still cached, through the second level cache I assume.

My runtime:

.NET 4.0 NHibernate: 3.1.0.4000 Fluent NHiberante: 1.2.0.712

My object:

[Serializable]
public class ArticleWishListItem : EntityBase<int>
{
    public virtual int CustomerId { get; set; }
    public virtual int ArticleId { get; set; }
    public virtual DateTime CreatedDate { get; set;  }
}

My mapping:

public class ArticleWishListItemMapping : ClassMap<ArticleWishListItem>
{
    public ArticleWishListItemMapping()
    {
        Cache.ReadWrite().Region("WishList");

        Id(a => a.Id).GeneratedBy.Native();

        Map(a => a.ArticleId).Not.Nullable();
        Map(a => a.CreatedDate).Not.Nullable();
        Map(a => a.CustomerId).Not.Nullable();
    }
}

My query where results are cached contrary to my wish:

    private static List<ArticleWishListItem> GetArticleWishListItemsImplementation(NHibernate.ISession session, int customerId)
    {
        return session.QueryOver<ArticleWishListItem>()
                                       .Where(a => a.CustomerId == customerId)
                                       .List<ArticleWishListItem>()
                                       .ToList<ArticleWishListItem>();
    }

What is the best way to make this query hit the database every time even though I want to have the the caching enabled for the entity? I can use IStatelessSession and it would work in this case because it skips the second level cache, but is it the recommended solution?

Upvotes: 2

Views: 3545

Answers (1)

Martin Ernst
Martin Ernst

Reputation: 5679

You need to use CacheMode.Ignore (will only invalidate the cache if updates occur), CacheMode.Refresh (will refresh all the items in the cache and ignore use_minimal_puts) or CacheMode.Put (will refresh any items that are invalid in the cache I think). The comments on the enumeration values tells you what they do a bit better.

eg:

return session.QueryOver<ArticleWishListItem>()
    .Where(a => a.CustomerId == customerId)
    .CacheMode(CacheMode.Refresh)
    .List<ArticleWishListItem>();

I'm not sure why you're calling .ToList again - that seems redundant to me as the call to .List will return a list already...

Upvotes: 4

Related Questions