Archive for the tag 'NHibernate'

NHibernate Caching Explained, finally!

Gabriel Schenker has just posted an excellent article explaining in detail how to the 1st and 2nd level cache in NHibernate works. This is a long overdue article on caching that will greatly benefit the community. The article also explains the differences between Get(id) and Load(id) when retrieving entities through NHibernate. I am recommending this article because it is an in depth look at one of the pieces I covered earlier on Ayende’s session from KaizenConf.

KaizenConf Workshops – Advanced NHibernate

As some of you know I am attending KaizenConf for the next few days. I am going to use my blog as my notepad as I take notes during different workshops and sessions. My note taking skills sometimes have a lot to be desired so be patient if these notes look very sketchy. I will try my best to come back through and make sense of them later.

Advanced NHibernate

I am currently sitting through Ayende’s workshop on Advanced NHibernate and there is some really good stuff going on here. Three of the topics I have found most interesting is Multi-Tenancy, Full text indexing with NHibernate Search, and caching with NHibernate. NHibernate search is a project that combines Lucene, a proven java index tool, and NHibernate to alleviate strain on the database engine by keeping indexes on disk and performing queries on that data faster. Indexing is accomplished by decorating entities with attributes. Of all these topics caching with NHibernate has really grabbed my attention as it probably has the greatest results for the applications I am currently working.

Caching with NHibernate

1st Level cache –Contains Identity Map – Session – Single instance of an object in a particular session

2nd Level Cache – contains the SessionFactory – lives for the entire application lifetime, it also has 4 levels of cache within it:

timestamp
query cache
collection cache
entity cache

 

Caching Configuration

Enable query cache <property name=”cache.use_second_level_cache”>True</property> in NHConfig – A single on off switch in the application to enable/disable caching is not a good solution because caching is complex and could affect business rules and performance. So you have to enable caching for a specific entity by using Cache_usage = CacheMode (ReadWrite for Ayende’s samples) in the entity mapping file. The NHibernate cache hashtables are stored like below:

Entities Cache:
————————-
Blog#1 : { Name: “…”}
Post#1 : {…}
Post#2 {…}

Collection Cache
—————————
Blog#1.Posts { 1,2,3,4,5,6} – stores id’s only

Query Cache:
—————————
“select top 5 * from Post” : {1,2,3,4} // stores id’s only

Ayende used his blog sample for all of the code examples today. When he put caching on the Blog, and the collection of posts in the blog map and on the post entity the fewest calls to the database occurred. To enable query caching the property cache.use_query_cache = true in the config file.

Session.Load vs Session.Get

Load == I know the entity exists in the database, it returns a proxy to the object. Throws an exception if the object is not lazy loaded and cannot be found.

Get == NH really goes to the database and fetches a row or throws an exception if it does not exist.

Which one of these to use depends on the business rule for the entity.

 

NHibernate Contrib project descriptions

NHibernate cache libraries:

PrevelanceCache – persistent caching for smart client applications

SysCache – using ASP.net caching – gives it the ability to put things in the cache and forget about it – only works if you have one machine.  Other wise you get cache poisoning.

SysCache2 – ASP.net caching in the farm – maybe application is not the only thing that updates the database. This is good when the application is not the sole owner of the database.

MemCache – a distributed hashtable, thats it basically it is distributed caching.– Server sitting on TCP with a hashtable – the Client caches the key and always goes back to same server in farm for cache retrieval. Very simple, works very well. This is also known as MemCacheD and is the same caching strategy that Facebook uses.

SharedCache – SharedCache from CodePlex

Velocity – From Microsoft – more complex than memcache, more options but they validate the cache space you have.

 

Other NHibernate Contrib Projects

NHibernate.Linq – pretty good, handles most of the common scenarios, does not handle the crazy scenarios that are capable in LINQ. Currently working on a fully functional LINQ library.

NHibernate.Validator– Just as you can specify constraints in SQL Server. You can specify constraints in your mapping file and the validator will validate that for you.

Spatial – GIS applications

Shards – partition the data across multiple db’s – written by Google to deal with problem of having multiple database. You can teach NHibernate a sharding strategy so that it knows which database to use. This is a strategy that is used by companies such as Facebook.

 

Another very interesting topic Ayende talked about is self optimizing queries. This would be used by session.Future<TYPE>() you could use this in your repositories on all lists/CreateCriteria methods. This creates a MultiCriteria which returns multiple result sets in one database trip. This is very similar/exactly like multiple result sets in stored procedures.

IRepository Code

This is by request from Frank Mao, he was wanting me to post up the code I am using for IRepository<T> so here it is:


public interface IRepository<T>
{
//IList<T> FetchList();
ICriteria CreateCriteria();
T Get(object id);
void Load(T obj, object id);
void Delete(T entity);

void DeleteAll();
void DeleteAll(DetachedCriteria where);
T Save(T entity);
T SaveOrUpdate(T entity);
T SaveOrUpdateCopy(T entity);
void Update(T entity);
long Count(DetachedCriteria criteria);
long Count();
bool Exists(DetachedCriteria criteria);
bool Exists();
IList<T> FindAll(DetachedCriteria criteria, params Order[] orders);
IList<T> FindAll(Order order, params ICriterion[] criteria);
IList<T> FindAll(Order[] orders, params ICriterion[] criteria);
T FindFirst(params Order[] orders);
T FindFirst(DetachedCriteria criteria, params Order[] orders);
T FindOne(params ICriterion[] criteria);
T FindOne(DetachedCriteria criteria);

ProjT ReportOne<ProjT>(ProjectionList projectionList);
ProjT ReportOne<ProjT>(DetachedCriteria criteria, ProjectionList projectionList);
IList<ProjT> ReportAll<ProjT>(ProjectionList projectionList);
IList<ProjT> ReportAll<ProjT>(bool distinctResults, ProjectionList projectionList);
IList<ProjT> ReportAll<ProjT>(ProjectionList projectionList, params Order[] orders);
IList<ProjT> ReportAll<ProjT>(bool distinctResults, ProjectionList projectionList, params Order[] orders);
IList<ProjT> ReportAll<ProjT>(DetachedCriteria criteria, ProjectionList projectionList, params Order[] orders);
IList<ProjT> ReportAll<ProjT>(bool distinctResults, DetachedCriteria criteria, ProjectionList projectionList, params Order[] orders);
}
}

I should note that this is a slightly modified version of IRepository that I got from the UnitOfWork tutorial code that is posted here: http://hibernatingrhinos.googlecode.com/svn/trunk/UnitOfWork/src/NHibernateRepository/

Csla Project Tracker + ObjectFactory + Altdotnet = Goodness

I will start off by giving my regular disclaimer, I am not an expert on this, however, I am also not an idiot either.

 

How It Was

 

We have been using Csla as a business object framework for about 3 years now and have had good results with it. That and we like things to just work and it does. Now a few months ago we started to get introduced to the altdotnet way and have seen the light and the need for many of the principles of altdotnet in our organization, it just makes sense. A few weeks ago Rhockford Lhotka release the beta version of Csla 3.6 and with it he has introduced support for an extensible ObjectFactory. This custom ObjectFactory takes the place of the DataPortal_XYZ() methods in the business object.

 

Now with the old way I had to make an object and write at least 3 lines of data access code for every property. This is cumbersome and just plain stinks. But good news! There is a better way.

 

The Better Way

 

So with this new ObjectFactory in Csla I can now spread some altdotnet goodness into my Csla projects. To be more specific here is what I have done, this has increased the dependencies of the project but has made the code much more flexible and easier to test.

Hopefully this little overview has intrigued you enough to go download the source code for the Csla sample redone with an ObjectFactory implementation. The source code and zip file are available at http://code.google.com/p/cslaptrackerfactory/ I will update the repository as I make changes/ additions to the code. I have created this as an open source project because I know that my method is not the only method and hopefully we can collectively come up with a way to use Csla with altdotnet goodies in a more standard way. So with that said, if you want to join the project, drop me a line.

 

I will post more articles that go in depth on how/why I did things a certain way in this project later, I hopw.

SQL Server Timestamp field and Fluent-NHibernate

This morning I was trying to do a Version mapping with Fluent-NHibernate on a timestamp column in a SQL database, this didn’t work so good right out of the box so I dug around and found some information here and there and once I pieced it together it all worked.

First off the mapping:


public class ProjectMap : ClassMap<Project>, IMapGenerator
{
        public ProjectMap()
        {
            WithTable("Projects");

            Id(x => x.Id)
                .GeneratedBy
                .GuidComb()
                .WithUnsavedValue("00000000-0000-0000-0000-000000000000");

            Map(x => x.Name)
                .WithLengthOf(50)
                .CanNotBeNull();

            Map(x => x.Started);
            Map(x => x.Ended);
            Map(x => x.Description);

            Version(x => x.TimeStamp)
                .TheColumnNameIs("LastChanged");
          }

}

public override VersionPart Version(System.Linq.Expressions.Expression<Func<ProjectResource, object>> expression)
{
     var versionPart = new VersionPart(ReflectionHelper.GetProperty(expression));

     versionPart.SetAttribute("type", "ProjectTracker.Library.Mapping.UserTypeTimestamp, ProjectTracker.Library");
     versionPart.SetAttribute("generated", "always");
     versionPart.SetAttribute("unsaved-value", "null");

     AddPart(versionPart);
     return versionPart;
}
 

The main thing here is the overridden Version method. What this override is doing is setting up a few attributes required to make this all work properly, I think most of them are self explanetory. Inside this method is a set attribute method that sets the type of the timestamp to UserTypeTimestamp. The coded for this class follows below:

UserTypeTimestamp Class:


public class UserTypeTimestamp : IUserVersionType
    {
        #region IUserVersionType Members

        public object Next(object current, ISessionImplementor session)
        {
            return current;
        }

        public object Seed(ISessionImplementor session)
        {
            return new byte[8];
        }

        public object Assemble(object cached, object owner)
        {
            return DeepCopy(cached);
        }

        public object DeepCopy(object value)
        {
            return value;
        }

        public object Disassemble(object value)
        {
            return DeepCopy(value);
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }

        public bool IsMutable
        {
            get { return false; }
        }

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            return rs.GetValue(rs.GetOrdinal(names[0]));
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            NHibernateUtil.Binary.NullSafeSet(cmd, value, index);
        }

        public object Replace(object original, object target, object owner)
        {
            return original;
        }

        public System.Type ReturnedType
        {
            get { return typeof(byte[]); }
        }

        public SqlType[] SqlTypes
        {
            get { return new SqlType[] { new SqlType(DbType.Binary) }; }
        }

        public int Compare(object x, object y)
        {
            byte[] xbytes = (byte[])x;
            byte[] ybytes = (byte[])y;
            if (xbytes.Length < ybytes.Length)
            {
                return -1;
            }
            if (xbytes.Length > ybytes.Length)
            {
                return 1;
            }
            for (int i = 0; i < xbytes.Length; i++)
            {
                if (xbytes[i] < ybytes[i])
                {
                    return -1;
                }
                if (xbytes[i] > ybytes[i])
                {
                    return 1;
                }
            }
            return 0;
        }

        bool IUserType.Equals(object x, object y)
        {
            return (x == y);
        }

        #endregion
    }

Now for the Business object change this:

private byte[] timeStamp = new byte[];

To this:


private byte[] timeStamp;
internal byte[] TimeStamp
{
     get { return timeStamp; }
     set { timeStamp = value;}
}

With the addition of the class and an internal Property so NHibernate can access the data in the timestamp everything works pefectly to implement optimistic concurrency with Fluent-NHibernate and SQL Server timestamp fields.

CSLA 3.6: Object Factory intro

We have been working the past few days on getting the new ObjectFactory up and running with CSLA 3.6. The approach we are taking is that we really want to abstract the Data Access Layer away from the Business Object so that we have some flexibility in the future to change the way we access the database. At the current time we are planning on using NHibernate as our ORM tool, one especially nice feature is that it is able to load your objects automatically so no more LoadProperty(SomeProperty) or ReadProperty(SomProperty) a million times. This one thing alone makes this very appealing to me.

 
  clip_image002

This diagram above is a representation of the basic architecture of the system. What we are basically doing is using the Repository pattern to keep data access decoupled from the business object through the use of the ObjectFactory and StructureMap. This is a setup very similar to what Frank is using in his project. However we are not using DTO objects in between the Repository and the business object. We might change this later but for now we will let the ORM load the objects directly.

I am currently working on implementing the ProjectTracker from the CSLA examples. My goal with this is to accomplish several things:

  1. Learn the ins and outs of the ObjectFactory and how it works with StructureMap, NHibernate, Mock Objects, TDD, etc..
  2. Provide a working drop in replacement to the “stock” ProjectTracker.Library, there shouldn’t be any changes required to the UI or anywhere else.
  3. Provide the source code so others can learn from what has been done and make contributions to make it work better or smoother and have it provide a model for people to base their frameworks off of.

So stay tuned because I will be adding more information here as I get closer, should be real soon. I will probably setup the source code on Google code or codeplex, if I do that let me know if you want to make contributions to the project.

CSLA + NHibernate = Easy

So we just started hacking around on a little project this afternoon where we hooked up a basic CSLA business object up to a database with NHibernate + Fluent NHibernate. All I have to say is that this was a breeze. There was a few nuances that had to be figured out before the object returned from the database correctly but that was just because I was doing something wrong I think. I am going to expand my sample some tomorrow and will try to post more code samples and the project soon.

So many doors, so many options, what a headache…

My head has finally stopped spinning enough that I can finally write this post. Before I dig into it though let me give some context. A few weeks ago a post by Kyle Baley shows up in my feed reader which is in response to a post by Roy Osherove. Now both of these posts were on the subject of whether the entry barrier to Software Development is to high. More specifically though these posts were directly targeting TDD, Agile, Mock Objects, Inversion of Control, Dependency Injection, NHibernate, etc… Just imagine for a minute you are in a round room with doors all around you. Each door looks the same and has a small yellow light hanging above it. Now, you have to pick a door, but which door do you pick? But You can peek into the door and see whats behind it without fully understanding whats in there, but that just makes your decision even harder. That’s kind of how I have been feeling the past few weeks trying to get my head wrapped around these things. With so much information out there about these technologies you may argue that it is not hard learn any one of them well. I agree with that, in fact I am not going to try to teach you about these technologies unless I find a gaping void somewhere. The complex part comes when you are trying to learn about these technologies together and/or how they are linked to each other. This all started from a conversation I had with Colin Jack  in reference to the above posts, which by the way were not the only discussion in blog land on the topic, we decided a road-map of some sort would be a good idea for people that are new to these “New Era Development Tools”. 

A disclaimer before we begin though. I am not an expert at any of these technologies, as such I welcome comments, criticism and just good ole’ corrections for anything I post that may be misleading or wrong. What I am though is a software developer that wants to understand and learn these technologies and principals and put them into practice developing software. So again, a little background. I am a Developer/Project Manager/many more hats for a small manufacturing company in Oklahoma. Our development team consists of 2-3 people at any given point. We have successfully developed and deployed several line of business applications over the past several years using C# and Rhockford Lhotka’s CSLA Business Objects. Now I know a lot of people embracing these new technologies don’t like CSLA but it works for us and the new version of the framework is going to play even nicer with these new technologies. Two months ago I didn’t even know what TDD (Test Driven Development) stood for let alone how to do it. But I got some books, did some research and I understand WHY we should do it and as awkward as it seems we are putting it in practice on a daily basis now.

This will be the first in a series of posts where I show you the “Roadmap” that I am taking to learn these technologies and make them work together. As I said above, I am by no means an expert on these topics, but I am learning and hopefully you will be learning as well. I will start at the bottom of these Building Blocks and work my way to the top. I may also add more blocks in the middle somwhere based on things learned on the way up.