Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate caching entities across sessions using SysCache

I'm developing a web application and I would like caching to persist across web requests. I am aware that the first level cache is per-session only. I have second-level caching enabled and this is working for queries.

However, the second-level cache does not seem to work for "getting" entities... therefore most of the DB work the application does is not being cached across web requests.

Is this normal / desirable behaviour? I'm reviewing one particular page that makes lots of round trips to the database, although each query is quick, these seem unnecessary if the entities could be cached.

Edit

Okay so I have second level cache enabled, and working for queries. I just can't seem to get it working for entities. I have Cache.Is(c => c.ReadWrite()) (fluent nhibernate) on my main entity that I'm testing. But nope, it still hits the DB each time. Any ideas?

Edit

I've tried using transactions like so:

public override Accommodation Get(int id) 
{ 
    using (var tx = Session.BeginTransaction()) 
    { 
        var accomm = Session.Get<Accommodation>(id); 
        tx.Commit(); 
        return accomm; 
    } 
} 

My mapping is such (and you can see we have a nasty schema):

public void Override(AutoMapping<Core.Entities.Itinerary.Accommodation.Accommodation> mapping)
{
    mapping.HasManyToMany(x => x.Features).Table("AccommodationLinkFeatureType").ChildKeyColumn("FeatureTypeId").NotFound.Ignore();
    mapping.HasManyToMany(x => x.SimilarAccommodation).Table("AccommodationLinkSimilarAccommodation").ChildKeyColumn("SimilarAccommodationId").NotFound.Ignore();
    mapping.HasMany(x => x.TourItinerary).Table("AccommodationTourItinerary");
    mapping.HasOne(x => x.Images).ForeignKey("AccommodationId").Cascade.All().Not.LazyLoad();
    mapping.References(x => x.CollectionType).NotFound.Ignore().Not.LazyLoad();
    mapping.References(x => x.AccommodationUnitType).NotFound.Ignore().Not.LazyLoad();
    Cache.Is(c => c.ReadWrite());
}

However, this still doesn't seem to fetch from the 2nd level cache.

Incidentally, I see a lot of examples online using Cache.ReadWrite() but I can only see an Is method on the Cache helper, so I'm trying Cache.Is(c => c.ReadWrite()) -- has the fluent interface changed?

like image 798
Chris Haines Avatar asked Oct 13 '10 15:10

Chris Haines


1 Answers

I have not tested this, but my understanding is that committing transactions is the magic that places objects into second level cache. If you are doing read operations outside of a transaction then the objects will not be placed in the second level cache.

like image 51
Jamie Ide Avatar answered Oct 14 '22 14:10

Jamie Ide