Dario Quintana

at blogging

StatelessSession: NHibernate without first-level cache

In the next NHibernate release will be available this feature ported by Fabio Maulo (key developer at NHibernate project), now it’s partial ready to test at trunk. What it does? In orden to get a NHibernate session without the first level cache we must use IStateless session interface (similar syntax to ISession). We must to remember using ISession that cache it’s mandatory, and until now it was imposible to work without it at NHibernate. For what? Was specially maded for bulk operations against the database. Check it out this code:

        using (ISessionFactory sf = cfg.BuildSessionFactory())
            {
                using (IStatelessSession session = sf.OpenStatelessSession())
                {
                    using (ITransaction tx = session.BeginTransaction())
                    {
                        Foo f = new Foo();

                        f.Id = 1;
                        f.Misc = "m1";
                        f.Name = "n1";

                        session.Insert(f);

                        f.Id = 2;

                        session.Insert(f);

                        tx.Commit();

                        Debug.Assert(session.CreateQuery("from Foo")
                                                    .List().Count == 2);
                    }
                }
            }

As you se, the f object was created once and sent to persist twice with the property Id changed, first with ’1′ and then with ’2′. And the result was 2 objects saved. In a common scenario with the first level cache this doesn’t work, because NHibernate “remember” the object f since was saved at first time and a error would be thrown. Notice to save the object we use Insert(…) instead Save(…). The sintax between IStalessSession and ISession are similar, not equals. To make work this example with first-level cache it’s mandatory that NHiberante “forget” the object that was saved. In order to get it, we need make Evict(…) – as you can image, this method are not included at IStatelessSession, even the Flush(…) method. The example look like this:

            using (ISessionFactory sf = cfg.BuildSessionFactory())
            {
                using (ISession session = sf.OpenSession())
                {
                    using (ITransaction tx = session.BeginTransaction())
                    {
                        Foo f1 = new Foo();

                        f1.Id = 1;
                        f1.Misc = "m1";
                        f1.Name = "n1";

                        session.Save(f1);

                        //Remove the object from cache
                        session.Evict(f1); 

                        f1.Id = 2;

                        session.Save(f1);

                        tx.Commit();

                        Debug.Assert(session.
                             CreateQuery("from Foo").List().Count == 2);

                    }
                }
            }

Resources:

  • Pingback: asNHibernate EventListeners at Dario Quintana

  • Pingback: NHibernate Stadistics - Go Fabio Go at Dario Quintana

  • Lee

    now a days NHibernate L2 caching is most efficient way to enhance the performance of the app as it reduces the time taking trips to DB and stores the frequently stored data. another wonderful thing for the developers is some of the distributed cache provider now also offer its rapper for NHibernate level caching. check it out here,
    http://www.alachisoft.com/ncache/nhibernate_l2cache_index.html

  • Waqas

    2 level caching is a wonderful way to enhance the performance of the NHibenate app as it reduces the time consuming trips to the database. there are a numbers of ways to have the L2 caching, one of them is the use of a third part cache provider which has the plug in for NHibernate L2 cache

  • http://www.etravelvn.com Quang

    Hi Dario,

    How to disable second-level cache?

    Thanks