NHibernate
What is the story behind the Entity Framework vs. NHibernate posts?
A while ago I posted several posts about EF vs. NH. They generated quite a bit of commentary, but while I enjoyed the discussion, I had an ulterior motive for doing so. I wanted to do this as a way to do a comparative research about the actual features that people would like to see in NHibernate.
NHibernate new feature: No proxy associations
About three weeks ago I introduced the problem of ghost objects in NHibernate. In short, given the following model: This code will not produce the expected result: var comment = s.Get<Comment>(8454);
if(comment.Post is Article)
{
//
}
NHibernate new feature: Lazy Properties
This feature is now available on the NHibernate trunk. Please note that it is currently only available when using the Castle Proxy Factory. Lazy properties is a very simple feature. Let us go back to my usual blog example, and take a look at the Post entity: As you can see, it is pretty simple example, but we have a problem. The Text property may contain a lot of text, and we don’t want to load that unless we explicitly asks for it. If we would try to execute this code: ...
Core NHibernate Course in London, 24th February
Well, it is about that time again :-) In about a month I’ll be returning to the UK to give another round of my NHibernate Course. It has been a while since I gave that in London, but the previous two runs were very successful, and I had great time teaching it. This course is meant to give you working knowledge how to effectively use NHibernate in your applications, based on real world expertise. You can register here: http://skillsmatter.com/course/open-source-dot-net/core-persistence-with-nhibernate
Eagerly loading entity associations efficiently with NHibernate
One of the things that seems to pop up frequently is people wanting to load an entity with all of its associations eagerly. That is pretty easy to do when the associations are many-to-one (that is, there is only one of them for each root entity). Example of those would be things like Owner, Site, etc. Here is an HQL query that would load a blog with its owner and site as well: from Blog b left join fetch b.Owner left join fetch b.Site
NHibernate, polymorphic associations and ghost objects
One of the more interesting points of my posts about Entity Framework & NHibernate is the discovery of things that Entity Framework can do that NHibernate cannot. In fact, if you’ll read the posts, instead of the comments, you can see that this is precisely what I asked, but people didn’t really read the text. I wanted to dedicate this post to ghost objects, and how NHibernate deals with them. Before we start, let me explain what ghost objects are. Let us say that you have a many to one polymorphic association, such as the...
Responding to Effectus commentary
Jose was kind enough to post a review of my sample Effectus application. This post is a reply to that. The first thing that Jose didn’t like was the fact that I didn’t put an abstraction layer in front of NHibernate’s usage in my application. There are several reasons for that, the first, and simplest, is that I was trying to explain how to use NHibernate, and for that, I wanted to deal with the lowest common denominator, not show off a particular wrapper implementation. Showing NHibernate usage directly means that even if you are using another library with...
Setting the record straight: I am not the main contributor to NHibernate
This is just something that bothers me. I’ll take credit where credit is due, but in this case, it isn’t. I am neither the owner of NHibernate nor the main contributor, as some people seems to think. According to ohloh, I am actually the #4 contributor, and if we will look at results from the last year alone, I would say that I am more likely to be #5 or #6. NHibernate is the work of many people, and it bothers me that people seems to think that because I talk about NHibernate frequently and for so long,...
Building a recommendation engine in NHibernate
Well, it isn’t really a recommendation engine, it is a sample of one, and I strongly recommend not using it, but I am getting ahead of myself. In the 6th episode of the TekPub’s NHibernate webcast, me & Rob worked on creating statistical queries with NHibernate. To be totally honest, the reason that we did that is to show off NHibernate’s querying capabilities, not so you would be able to make use of this in your applications. A recommendation engine is not something that you should run out of your OLTP store, so please take that under advisement. ...
NHibernate is on the cover of MSDN Magazine
A while ago I run a poll about what posts you would like me to do, and the most requested topic was handling NHibernate in a Desktop application. I started writing a blog post about it, but when it hit twenty pages, I thought better on that and decided that I might as well post that as an article. MSDN Magazine just did. You can read the about Building a Desktop To-Do Application with NHibernate in the latest issue of MSDN Magazine. And now that the article is out, I can start posting about other topic in the...
NHibernate Course – Aarhus, Denmark @ Dec 09
There are still available places for my 3 days course about NHibernate in Aarhus on December 9th. This course is aimed at developers who are new to NHibernate or those who want to amp up their NHibernate knowledge. In the course, we go over mapping options, queries and optimizations, caching, extensibility options and a whole lot more. I gave this course several times already, and it is pretty intense, but at the end of it, you are going to come out knowing NHibernate. You can register to the course here: http://skillsmatter.com/course/open-source-dot-net/core-persistence-with-nhibernate
NHibernate – Cross session operations
This started out as a support question, but it is an interesting enough (and general enough) that I think it is important to make sure that it is recorded. When working with detached entities (from another session), sometimes, at seemingly random places, NHibernate will throw a NonUniqueObjectException. Where it actually happen and the exact cause depend on several variables, but the root problem is simple: working with detached entities safely requires that you be aware of possible identity map violations. Let us look at some code and then I can explain: ...
I don’t do math, or how to get a €50 discount to NH Prof
Okay, here is how it goes. Go to TekPub and subscribe to the NHibernate series (this cost $25). One of the perks in the TekPub’s NHibernate series is a €50 coupon code (about $75) for NH Prof. End result, you save $50 overall, and you get access to a lot content teaching you about NHibernate from all directions.
NHibernate webcasts series
Rob Conery and I had sat down and started recording a series of webcasts on NHibernate, which will show up on TekPub. TekPub is a paid service, and there are two NHibernate screen casts there already. We plan to have lots more. I got a lot of requests for making my NHibernate courses available to a wider audience. And this is a way for you to get a ton of NHibernate content. So far the reactions that we got were very positive. Oh, and as a side effect, you get to see NH Prof used by the person...
Database independence with NHibernate
Karl has posted about his experience of porting an NHibernate application from SQL Server to PostgreSQL, long story short, he did it in 1 hour. He does bring up a few points where the database that he was using bled into the code, hurting the database independence goal. I wanted to look at those and point out the builtin solutions that NHibernate provides for those. Handling unique constraints violations, Karl has code like this: try
{
Session.SaveOrUpdate(user);
transaction.Commit();
return true;
}
catch (GenericADOException ex)
{
transaction.Rollback();
...
Core NHibernate: Persistence with NHibernate – Coming to Paris
My 3 days course about NHibernate will be delivered at Paris , on 04 Nov 2009 by Sebastien Lambla. This course is squeezing into 3 days everything that you need to go from an NHibernate newbie to a proficient craftsman. An interesting tidbit, the last time that Sebastien gave the course, I got amazing feedback about the course. You can register here.
NHibernate Shards: Progress Report
Since my last post about it, there has been a lot of changes to NHibernate Shards. Update: I can’t believe I forgot, I was so caught up in how cool this was that I did give the proper credits. Thanks to Dario Quintana and all the other contributors to NHibernate Shards. The demo actually works :-) You can look at the latest code here: http://nhcontrib.svn.sourceforge.net/svnroot/nhcontrib/trunk/src/NHibernate.Shards/ You can read the documentation for the Java version (most of which is applicable for the .NET version) here: http://docs.jboss.org/hibernate/stable/shards/reference/en/html/ Let us go through how it...
Choosing between Active Record, Fluent NHibernate and NHibernate
A forum question:
I have seen videos where you created a domain model using ActiveRecord in real-time... elaborate on when and how you move to using full Hibernate in more detail.
The problem with presentations such as the one described in the question is that they are cheating. Oh, I really do work things on the fly, but it is like asking me to type with my eyes closed (as I am doing right now, just to see if I can).
I can do that, but it doesn’t really say much about my typing skills. The type of models that I create live...
JAOO: OR/M += 2
Just finished doing this presentation, I think it went very well, although I planned to do a 45 minutes session + 15 questions but I ended up hitting the session time limit without covering everything that I wanted. You can get the source code that I have shown in the presentation here: http://github.com/ayende/Advanced.NHibernate You can find the PDF of the presentation here: http://ayende.com/presentations.aspx
Random NHibernate tweets
Those crossed my desk recently, and I thought they were interesting. I am seeing more and more movement behind NHibernate.
More NHibernate commercial support options
The NHibernate scene is growing bigger. I am starting to see NHibernate related jobs crossing me mailbox, NHibernate 2.1 downloads crossed the 20,000 downloads a while ago and a very active mailing list. iMeta, who sponsored the development of the AST based parser and is currently sponsoring the Linq for NHibernate effort, is now also offering Commercial Support for NHibernate. This is a separate offer from mine, and seems to be targeting a different audience. From my point of view, the more the merrier, it simply shows that the market for NHibernate is growing, fast.
Append Only Models with NHibernate
I mentioned that using an append only model isn’t just an infrastructure choice, it has a big effect on your API and your general approach to working with your model. Let us look at a typical example of change the martial status of an employee: // transaction is opened before method by the infrastructurepublic void Consume(ChangeMaritalStatus msg){ var emp = Session.Get<Employee>(msg.EmployeeId); emp.ChangeMaritalStatus(msg.NewMaritalStatus, msg.MaybeNewSurname);}/* transaction is committed here and changes are flushed to the databaseby the infrastructure*/
As you can see, using this approach,...
Commercial Support for NHibernate
One of the oft repeated objections to using NHibernate is that there isn’t someone that you can officially complain to. Some organizations put great store in having someone to officially complain to :-). The NHibernate community, especially the NHibernate Users mailing list is active and thriving, and a large percentage of the support questions that you may have can be answered there, for free. However, there are situations where you really do want to have someone to call to get you out of the foxhole. And there are organizations that will not accept a technology unless they...
SQL Azure, Sharding and NHibernate: A call for volunteers
I was quite surprised to hear that SQL Azure has a 10 GB limit for each database. That drastically reduce the amount of effort that I guess SQL Azure takes. At a guess, I would say it is simply replicated instances of databases instead of real SQL on the cloud. One of the nice premises of working on the cloud is that you get transparent scaling. 10GB limit is not transparent. The answer from Microsoft seems to be that you need to implement Sharding. That is, you spread your logical database over several physical databases. Usually it is...
NHibernate on the cloud: SQL Azure
I just finished running the NHibernate test suite against SQL Azure. I am very happy to say that It Just Works*. Hat tip for Microsoft for managing to create an environment so similar to that of SQL Server under a drastically different conditions. * The only caveat is that some Schema Export scripts fails on SQL Azure, it seems like drop table has some slightly different behavior with SQL Azure, it does not drop the table immediately, but there seems to be some delay before it actually happens (especially if you use a...
Avoid Soft Deletes
One of the annoyances that we have to deal when building enterprise applications is the requirement that no data shall be lost. The usual response to that is to introduce a WasDeleted or an IsActive column in the database and implement deletes as an update that would set that flag. Simple, easy to understand, quick to implement and explain. It is also, quite often, wrong. The problem is that deletion of a row or an entity is rarely a simple event. It effect not only the data in the model, but also the shape of the model....
NHibernate tips & tricks: Efficiently selecting a tree
I run into the following in a code base that is currently being converted to use NHibernate from a hand rolled data access layer. private void GetHierarchyRecursive(int empId, List<Employee> emps) {
List<Employee> subEmps = GetEmployeesManagedBy(empId);
foreach (Employee c in subEmps) {
emps.Add(c);
GetHierarchyRecursive(c.EmployeeID, c.ManagedEmployees);
}
}
GetHierarchyRecursive is a method that hits the database. In my book, a method that is calling the database in a loop is guilt of a bug until proven...
NHibernate rarities: SessionFactoryObjectFactory
I had a discussion about session factory management in NHibernate just now, and I was asked why NHibernate isn’t managing that internally. Well… it does, actually. As you can guess, SessionFactoryObjectFactory is the one responsible for that, and you can use GetNamedInstance() to get a specific session factory. It isn’t used much (as a matter of fact, I have never seen it used), I am not quite sure why. I think that it is easier to just manage it ourselves. There are very rare cases where you would need more than one or two session factories, and when...
NHibernate Documentation
I know that some people complain about the lack of documentation with NHibernate. That is something that I never truly could grasp. Leaving aside the excellent book, right there in NHibernate’s site we have a huge amount of documentation. I’ll admit that the plot in the documentation is weak, but I think that reading this document is essential. It covers just about every aspect of NHibernate, and more importantly, it allows you to understand the design decisions and constraints that were used when building it. Next time you wonder about NHibernate Documentation, just head over there and check....
NHibernate Perf Tricks
I originally titled this post NHibernate Stupid Perf Tricks, but decided to remove that. The purpose of this post is to show some performance optimizations that you can take advantage of with NHibernate. This is not a benchmark, the results aren’t useful for anything except comparing to one another. I would also like to remind you that NHibernate isn’t intended for ETL scenarios, if you desire that, you probably want to look into ETL tools, rather than an OR/M developed for OLTP scenarios. There is a wide scope for performance improvements outside what is shown here, for example, the...
Benchmark cheating, a how to
I already talked about the benchmark in general, but I want to focus for a bit on showing how you can carefully craft a benchmark to say exactly what you want. Case in point, Alex Yakunin has claimed that NHibernate is: NH runs a simple query fetching 1 instance 100+ times slower when ~ 10K instances are already fetched into the Session I am assuming that he is basing his numbers of this test: And you know what, he is right. NHibernate will get progressively slower as more items are...
What is the cost of opening a session?
Damien Guard asked me an interesting question: Is SessionFactory.OpenSession() very lightweight because you call it on every request even if you have pages that don't need it. I would have thought the lazy construction in CurrentSession get would have been a little safer. The answer is that it is literally not worth your time to write the lazy construction. Here is what is happening when you opening a session: public ISession OpenSession(IDbConnection connection, bool flushBeforeCompletionEnabled, bool autoCloseSessionEnabled,
ConnectionReleaseMode connectionReleaseMode)
{
return
new SessionImpl(connection, this, true, settings.CacheProvider.NextTimestamp(), interceptor,
settings.DefaultEntityMode, flushBeforeCompletionEnabled, autoCloseSessionEnabled,
connectionReleaseMode);
}
We...
Benchmarks are useless, yes, again
I was informed about ORMBattle.NET existence a few minutes ago. This is a site that: ORMBattle.NET is devoted to direct ORM comparison. We compare quality of essential features of well-known ORM products for .NET framework, so this site might help you to: Compare the performance of your own solution (based on a particular ORM listed here) with peak its performance that can be reached on this ORM, and thus, likely, to improve it. Choose the ORM for your...
Nhibernate Unit of Work & multiple reuqests
Another post request from the forum: Oren, I'd love to get some detail on how to make the most of NHibernate's unit of work capability in a web app scenario. It seems like in a web app, because your unit of work may be split across multiple web requests (and therefore sessions), it's hard to use NHibernate's change tracking etc effectively and I find myself doing unit of work tracking myself. This seems to lead inevitably to an anaemic domain model and feels like...
Emancipating NHibernate from Hibernate?
This is an answer to a post request in the forum: Why keep NHibernate tied to Hibernate or is it not tied to it anymore? (NHibernate would be easier to pick up if the nomenclature wasn't ripped from Hibernate, ie AliasToBeanResultTransformer, etc...) There are two separate questions here that needs answering. The first is easier, we keep NHibernate close to Hibernate because it makes our lives so much easier. By keeping the code bases close to one another, we can more easily port new features, documentation and bug fixes. There are no plans, and...
NHibernate & INotifyPropertyChanged
One of the things that make NHibernate easy to use is that it fully support the POCO model. But one of the things that most people do not consider is that since NHibernate did the hard work of opening up the seams to allow external persistence concerns, we can use the same seams to handle similar infrastructure chores externally, without affecting the POCO-ness of our entities. Allow me to show you what I mean. First, we create the following factory, which makes use of Castle Dynamic Proxy to weave in support for INotifyPropertyChanged in a seamless manner: ...
NHibernate and Silverlight Server Side Integration
After tell you that NHibernate and Silverlight will never play ball on the client side, I got a lot of requests for showing how we can integrate NHibernate on the server side with a Silverlight application. Mostly, such things are done using RIA services. Brad Adams has just posted how to do just that. Go check it out.
Do you need a framework?
I had a discussion about a session life style management, and the guy I was talking with mentioned a framework that would handle that for me. It made me think for a while, because my first instinct was to ask, what for? Here is how I usually handle session life style management in web applications nowadays: public class Global: System.Web.HttpApplication
{
public static ISessionFactory SessionFactory = CreateSessionFactory();
protected static ISessionFactory CreateSessionFactory()
{
return new Configuration()
.Configure(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "hibernate.cfg.xml"))
.BuildSessionFactory();
}
public static ISession CurrentSession
{
get{ return (ISession)HttpContext.Current.Items["current.session"]; }
set { HttpContext.Current.Items["current.session"] = value; }
}
protected void Global()
{
BeginRequest += delegate
{
CurrentSession = SessionFactory.OpenSession();
};
EndRequest += delegate
{
if(CurrentSession != null)
CurrentSession.Dispose();
};
}
}
And yes, I copy...
A short note about NHibernate and Silverlight
I got a few questions about NHibernate and Silverlight. That is actually a very easy thing to answer. Don’t even try. They don’t get along. In fact, they aren’t even going to get along. Silverlight doesn’t have System.Data.IDbConnection, and you can safely assume that that it somewhat important to NHibernate. So, running NHibernate inside a Silverlight application, presumably in order to access a local database is out. But I don’t think that this is what most people actually had in mind when they ask about NHibernate and Silverlight. They want to know about NHibernate on...
NHibernate Linq 1.0 released!
The most requested feature for NHibernate for the last few years has been Linq support, and it gives me great pleasure to announce the release of NHibernate Linq 1.0 RTM, which you can download from here. NHibernate Linq support is based on the existing, proven in production, Linq provider in NHibernate Contrib. The plans to overhaul that and merge that into NHibernate’s proper for the next release are still active, but the project team feels most strongly that production quality Linq support is something that we ought to provide for our users now. This Linq release support just...
NHibernate and NDepend – skimming the surface
Well, you are probably are already aware of the long discussion that I had about it. Patrick was kind enough to help me get to the actual information that I was interested at, and now I can try to talk with concrete data. The post is based on skimming the following matrix: But the reason that I am skimming is that the matrix size is just too big to really go over by hand. The matrix is showing dependencies between different types. Here is an area that seems to be rich in cycles:...
Answering to NHibernate codebase quality criticism
Patrick has a post analyzing the changes to NHibernate 2.1, which I take exception to. Specifically, to this: Now, the code base is completely entangled and it must be a daily pain to maintain the code. There is a total lack of componentization and each modification might potentially affect the whole code base. Um… not! The problem with the way things are seen from Patrick’s point of view is that his metrics and the metrics used by the NHibernate team are not identical. As a matter of fact, they are widely divergent. This...
NHibernate 2.1 is out!
NHibernate 2.1 GA (RTM) was released, Download it! There are many good changes (check the release notes) and I strongly recommend moving to it. I would like to personally thank Fabio for the tremendous amount of work that he put into it, as well as to all the other members of the team.
Another round of NHibernate courses
Well, it is time to start thinking about the next round of NHibernate courses. The next one is on August 12th, in London, UK. The previous two courses that I taught there went very well, and the response from the students was quite positive. There are still reservations available, so you might want to hurry up and book it now.
NHibernate - <natural-id/>
A natural id is a way to refer to a unique field of an object as a substitute of the real entity identifier. A good (and typical) example of that would be with the User entity. We have the user name and the user id, both are unique, but the user id is usually something that is generated by our application and has no relation to the a human being. In other words, user #123814 doesn’t mean anything to me, while user ‘ayende’ has a meaning to us. There are many reasons for choosing this approach, but the most...
NH Prof: NHibernate Profiler vs. Sql Profiler
I recently got a question, asking why someone should pay for NH Prof if SQL profiler is available for (effectively) free? The answer is actually very easy to answer. I run the following scenario through both NH Prof and SQL Profiler: using (var s = sf.OpenSession())
using (var tx = s.BeginTransaction())
{
s.CreateCriteria<User>()
.Add(Restrictions.NaturalId()
.Set("Username", "Ayende"))
.SetCacheable(true)
.UniqueResult();
tx.Commit();
}
using (var s = sf.OpenSession())
using (var tx = s.BeginTransaction())
{
s.CreateCriteria<User>()
.Add(Restrictions.NaturalId()
.Set("Username", "Ayende"))
.SetCacheable(true)
.UniqueResult();
tx.Commit();
}
Here is what NH Prof gave me:
And here is what I got from SQL Profiler:
I think that I have rested my case, pretty conclusively.
NHibernate – Automatic change tracking for aggregate roots in DDD scenarios
Recently I had a long discussion with Greg Young about the need of this feature, and after spending some time talking to him face to face we were able to reach an understanding on what exactly is required to make this work. Basically, the feature that Greg would like to see is to write code like this and have NHibernate take care of optimistically locking the aggregate. using (var s = sf.OpenSession())
using (var tx = s.BeginTransaction())
{
var post = s.Get<Post>(postId);
post.AddComment(new Comment
...
NHibernate – query only properties
With most applications, there is some difference between the domain model and the data model. Probably the most common scenario that I run into can be expressed in the usually Blog & Posts example. In our domain model, we don’t want to have a Blog.Posts collection, we want to only have a Post.Blog. However, in the data model, all associations are bidirectional, but that doesn’t mean that we want to have the same in the domain model. The problem is that we still want to query on that. That is a bummer, right? Because now we have to change...
NHibernate – Get Thou Out Of My Database – 2nd Edition
Following up on my previous post, the customer has complained about table names like [tbl_-1434067361], apparently they felt that this was misusing their naming policy. I told them that while I understood that, it did meet their naming policy. I got a new naming policy that stated that numbers are not allowed in column or table name, (and showing forethought) that table names must be composed of valid English words. I, of course, decided that if this is what they wanted, they will get just that. And created this: The words.txt file was taken from...
NHibernate – Get Thou Out Of My Database
There are evil people in this world, and some of them want access to my database. Unfortunately, they are often part of that nasty integration team and they try to integrate directly into my database. I tried beating them with clubs and lobbing arguments about letting other people mess with my implementation details, but they have been persistent. That is when I reached out to a technological solution for the problem. I want to emphasize that this is the nuclear option and you want to really consider it before going that route. We are going to use...
NHibernate – Beware of inadvisably applied caching strategies
One of the usual approaches for performance problems with most applications is to just throw caching on the problem until it goes away. NHibernate supports a very sophisticated caching mechanism, but, by default, it is disabled. Not only that, but there are multiple levels of opt ins that you have to explicitly state before you can benefit from caching. Why is that? The answer is quite simple, caching is an incredibly sensitive topic, involving such things as data freshness, target size, repetitive requests, etc. Each and every time I have seen caching used as a hammer, it...
NHibernate Mapping – <map/>
I am not going to talk about all the options that NHibernate has for collections, I already did it for <set/>, and most of that are pretty similar. Instead, I am going to show off the unique features of NHibernate’s <map/>, and then some how crazy you can get with it. Let us start with the simplest possible scenario, a key/value strings collection, which looks like this: public class User
{
public virtual int Id { get; set; }
public virtual string Name { get;...
NHibernate Mapping - <list/>
I am not going to talk about all the options that NHibernate has for collections, I already did it for <set/>, and most of that are pretty similar. Instead, I am going to show just the unique stuff about NHibernate’s <list//>. While <set/> is an unordered collection, of unique elements, a <list/> is a collection of elements where the order matter, and duplicate elements are allowed (because there is a difference between item A in index 0 and index 4). Let us look at what it means by looking at the class itself: ...
NHibernate Queries – Should I use HQL or Criteria?
This is a common question that I get asked, what is better? What should I use? The actual answer is complex, and some of it, at least, depends on personal preferences. More than that, it also depends on the type of queries that you have. In general, all queries fall into one of the following distinctions: Select by Id select * from Blogs where id = @id Select by fixed criteria (parameters may change, but the actual query itself is fixed)...
NH Prof & Teaching NHibernate
I have taught NHibernate both before and after NH Prof was available. I have to say, there is absolutely no way that I can compare the two. NH Prof, I know that I am not suppose to say that, but I love you. I really love you! I am saying this after spending 4 days doing intensive NHibernate stuff, a full 3 days course and NHibernate consulting day. And NH Prof made it so much easier that I cannot really describe. Participants in my course can testify how at several points I...
NHibernate – Coarse Grained Locks
One of the challenges that DDD advocates face when using an OR/M is the usage of Coarse Grained Locks on Aggregate Roots, I’ll leave the discussion of you would want to do that to Fowler and Evans, but it seems that a lot of people run into a lot of problems with this. It is actually not complicated at all, all you have to do is call: session.Lock(person, LockMode.Force); This will make NHibernate issue the following statement: This allow us to update the version of the aggregate even...
Poor man’s guide to database optimization - by the Marquis de Sade
One of the more common problems that I see over and over again in many applications is that test databases are too fast. As I have shown, this can easily lead to really sever cases of chattiness with the database, and all while the developer is totally oblivious. This is especially true when you develop against a local database with almost no data, and deploy to a network database with lots of data. SELECT N+1 is bad enough, but when N is in the hundreds or more, it gets bad. The main problem is that developers aren’t really aware...
NHibernate – Executable DML
This is a new feature of NHibernate that Fabio has recently ported. Using the same model that I have talked about before: With the following schema: The feature is basically this, NHibernate can now execute set based operation on your model. This include all Data Modification Language operations, so we are talking about Update, Insert and Delete. Let us make things a bit interesting and talk about the following statement, which hopefully will make things clearer: s.CreateQuery("update Owner o set o.Name = 'a'...
NHibernate: Why do we need to specify the query type twice?
Why do we have to do something like that? var blogs = s.CreateCriteria<Blog>()
.Add(Restrictions.Eq("Title", "Ayende @ Rahien"))
.List<Blog>();
We have to specify Blog twice, isn’t that redundant?
Yes and no. The problem is that we can’t assume that we are going to return instances of Blog. For example:
var blogs = s.CreateCriteria<Blog>()
.Add(Restrictions.Eq("Title", "Ayende @ Rahien"))
.SetProjection(Projections.Id())
.List<int>();
NHibernate – Help us see who is using it
One of the most frustrating things about working on Open Source projects is that you don’t have feedback about your users unless they have a problem. During my Progressive.NET NHibernate workshop, there was hardly place in a big room, and talking about this issue with the attendees afterward, I kept hearing things like: “I have seen NHibernate used in my last 3 jobs”, or “We have been using NHibernate for the last 2 years.”
On the one hand, it is heartwarming to hear that, on the other, it is incredibly frustrating not knowing.
If you are using NHibernate, I would like to...
NHibernate – Mapping a single domain model to multiple physical data models
A while ago I sat down and talked with a colleague about the Entity Framework, he raved about how important the separation of the logical model from the physical one is. I don’t really buy into that, but that is beside the point. Last week, on the Progressive.NET NHibernate workshops, I setup, quite accidently, to create a single domain model and map it to several physical data models. I promised to share the code, and I think that this form is as good as any. Let us start from the following domain model: ...
NHibernate Queries - Examples
Today was the first day of my NHibernate course, and I think that it might be good to point out a few of the samples that we worked with. Those are pretty basic NHibernate queries, but they are probably going to be useful for beginners.
Let us take my usual Blog model, and see what kind of queries (and results) we can come up with:
Let us find a blog by its identifier:
var blog = s.Get<Blog>(1);
Which results in:
We can also try:
var blog = s.Load<Blog>(1);
Which would result in… absolutely no SQL queries. You can look at a more deep discussion of that...
Code from Persistence.NET NHibernate Workshops
The relevant code from the live coding exercise can be found here, and it is probably going to be the basis of most of the demos that I am going to do. Have fun playing with it…
NHibernate Filters
One of the more interesting ability of NHibernate is to selectively filter records based on some global filters. This allow us to very easily create global where clauses that we can flip on and off at the touch of a switch. Let us take a look at see what I mean. We define the filter effectiveDate: <filter-def name="effectiveDate">
<filter-param name="asOfDate" type="System.DateTime"/>
</filter-def>
A filter definition is most commonly just a set of parameters that we can define, which will later be applied to in the appropriate places. An example of an appropriate place would be Post.PostedAt,...
NHibernate Search
NHibernate Search is an extension to NHibernate that allows you to utilize Lucene.NET, a full text search engine as your query engine, instead of putting additional load on the database itself. In a sense, this is a good way outsource your queries from the database. This has several chief advantages: Your database is now mostly about performing queries by primary key (fast) and handling data storage, transactional semantics, etc. All of which should be very fast. Your costly queries can now run on a different (cheap) machine, and a long query isn’t...
NHibernate, the database query cache and parameter sizes
A while ago I took part in a herding code episode where the question was brought up, what would NHibernate’s behavior would be in the following scenario? s.CreateQuery("from Blog b where b.Title = :title")
.SetString("title","hello")
.List();
s.CreateQuery("from Blog b where b.Title = :title")
.SetString("title", "hello world")
.List();
The actual problem related more to the way NHibernate interacts with the database than to the way NHibernate itself works. The issue was whether or not NHibernate will generate a query that will reuse the same query plan for parameters with different sizes, or whatever it will generate a copy of the query plan for...
NHibernate Validator
Validation is one of those things that goes hand in hand with data access. I guess it is not much of surprise that one of the contrib projects for NHibernate is extensive validation support. True, there are about as many validation frameworks as there are ToDo applications, but NHibernate Validator bring something special to the table, it brings tight integration with NHibernate itself and: “…multi-layered data validation, where constraints are expressed in a single place and checked in various different layers of the application.” I am sorry, I just love this quote. :-)...
NHibernate – The difference between Get, Load and querying by id
One of the more common mistakes that I see people doing with NHibernate is related to how they are loading entities by the primary key. This is because there are important differences between the three options. The most common mistake that I see is using a query to load by id. in particular when using Linq for NHibernate. var customer = (
select customer from s.Linq<Customer>()
where customer.Id = customerId
select customer
).FirstOrDefault();
Every time that I see something like that, I wince a little inside. The reason for that is quite simple. This is doing a query by primary...
NHibernate IPreUpdateEventListener & IPreInsertEventListener
NHibernate’s listeners architecture bring with it a lot of power to the game, but understanding how to use it some of the listeners properly may require some additional knowledge. In this post, I want to talk specifically about the pre update hooks that NHibernate provides. Those allow us to execute our custom logic before the update / insert is sent to the database. On the face of it, it seems like a trivial task, but there are some subtleties that we need to consider when we use them. Those hooks run awfully late in the processing pipeline, that...
NHibernate Unit Testing
When using NHibernate we generally want to test only three things, that properties are persisted, that cascade works as expected and that queries return the correct result. In order to do all of those, we generally have to talk to a real database, trying to fake any of those at this level is futile and going to be very complicated. We can either use a standard RDBMS or use an in memory database such as SQLite in order to get very speedy tests. I have a pretty big implementation of a base class for unit testing NHibernate in...
NHibernate Futures
One of the nicest new features in NHibernate 2.1 is the Future<T>() and FutureValue<T>() functions. They essentially function as a way to defer query execution to a later date, at which point NHibernate will have more information about what the application is supposed to do, and optimize for it accordingly. This build on an existing feature of NHibernate, Multi Queries, but does so in a way that is easy to use and almost seamless. Let us take a look at the following piece of code: using (var s = sf.OpenSession())
using (var tx = s.BeginTransaction())
{
var blogs...
NHibernate 2nd Level Cache
NHibernate has a builtin support for caching. It sounds like a trivial feature at first, until you realize how significant it is that the underlying data access infrastructure already implements it. It means that you don’t have to worry about thread safety, propagating changes in a farm, built smart cache invalidation strategies or deal with all of the messy details that are usually along for the ride when you need to implement a non trivial infrastructure piece. And no, it isn’t as simple as just shoving a value to the cache. I spent quite a bit of time...
NHibernate Tidbit – using <set/> without referencing Iesi.Collections
Some people don’t like having to reference Iesi.Collections in order to use NHibernate <set/> mapping. With NHibernate 2.1, this is possible, since we finally have a set type in the actual BCL. We still don’t have an ISet<T> interface, unfortunately, but that is all right, we can get by with ICollection<T>. In other words, any ISet<T> association that you have can be replaced with an ICollection<T> and instead of initializing it with Iesi.Collections.Generic.HashedSet<T>, you can initialize it with System.Collections.Generic.HashSet<T>. Note that you still need to deploy Iesi.Collections with your NHibernate application, but that is all, you can remove...
Using Active Record to write less code
The presentations from Oredev are now available, and among them is my talk about Active Record. You can watch it here, the blurb is: What would you say if I told you that you can stop writing data access code in .Net? Aren't you tired of writing the same thing over and over again, opening connection, querying the database, figuring out what to return, getting back untype data that you need to start putting on the form? Do you really see some value in writing yet another UPDATE statement?The Active Record framework allows you to...
NHibernate Mapping - <many-to-any/>
<many-to-any/> is the logical extension of the <any/> feature that NHibernate has. At the time of this writing, if you do a Google search on <many-to-any/>, the first result is this post. It was written by me, in 2005, and contains absolutely zero useful information. Time to fix that. Following up on the <any/> post, let us say that we need to map not a single heterogeneous association, but a multiple heterogeneous one, such as this: In the database, it would appear as: How can we map such a thing? ...
NHibernate Mapping - <any/>
Sometimes, well known associations just don’t cut it. We sometimes need to be able to go not to a single table, but to a collection of table. For example, let us say that an order can be paid using a credit card or a wire transfer. The data about those are stored in different tables, and even in the object model, there is no inheritance association them. From the database perspective, it looks like this: As you can see, based on the payment type, we need to get the data from a different table. That...
NHibernate Mapping - <join/>
We have previously explored the one-to-one mapping, which let you create 1:1 association in the database, but there is actually another way to map several tables to an object model. We aren’t constrained by the database model, and we can merge several tables into a single entity. We do that using the <join/> element: <join
table="tablename" (1)
...
NHibernate Mapping - <one-to-one/>
In the database world, we have three kind of associations: 1:m, m:1, m:n. However, occasionally we want to have a one to one relationship. We could simulate it easily enough on the database side using two many to one relations, but that would require us to add the association column to both tables, and things gets… tricky when it comes the time to insert or update to the database, because of the cycle that this creates. NHibernate solves the problem by introducing a one-to-one mapping association, which allow you to define the two relationships based on a single...
Mocking NHibernate
My recent post caused quite a few comments, many of them about two major topics. The first is the mockability of my approach and the second is regarding the separation of layers. This post is about the first concern. I don’t usually mock my database when using NHibernate. I use an in memory database and leave it at that. There are usually two common behaviors for loading data from the database. The first is when you need to load by primary key, usually using either Get or Load, the second is using a query. If we are using...
Repository is the new Singleton
I mentioned in passing that I don’t like the Repository pattern anymore much, and gotten a lot of responses to that. This is the answering post, and yes, the title was chosen to get a rise out of you. There are actually two separate issues that needs to be handled here. One of them is my issues with the actual pattern and the second is the pattern usage. There most commonly used definition for Repository is defined in Patterns of Enterprise Application Architecture: A system with a complex domain model often benefits from a layer,...
NHibernate Mapping – Named queries <query/> and <sql-query/>
Queries are business logic, as such, they can be pretty complex, and they also tend to be pretty perf sensitive. As such, you usually want to have a good control over any complex queries. You can do that by extracting your queries to the mapping, so they don’t reside, hardcoded, in the code: <query name="PeopleByName">
from Person p
where p.Name like :name
</query>
And you can execute it with:
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
session.GetNamedQuery("PeopleByName")
.SetParameter("name", "ayende")
.List();
tx.Commit();
}
PeopleByName is a pretty standard query, and executing this code will result in:
Now, let us say that we discovered some...
NHibernate mapping - <database-object/>
I, like many, have grown used to NHibernate’s schema generation capabilities. Those make working with databases such a pleasure that I cannot imagine trying without them. However, at some point, even NHibernate’s smarts reach an end, and such an occasion requires the use of direct SQL to manipulate the database directly. A good example of that would be: <!-- SQL Server need this index -->
<database-object>
<create>
CREATE INDEX PeopleByCityAndLastName ...
</create>
<drop>
DROP INDEX PeopleByCityAndLastName
</drop>
<dialect-scope name="NHibernate.Dialect.MsSql2000Dialect"/>
<dialect-scope name="NHibernate.Dialect.MsSql2005Dialect"/>
<dialect-scope name="NHibernate.Dialect.MsSql2008Dialect"/>
</database-object>
<!-- Oracle need this stats only -->
<database-object>
<create>
CREATE STATISTICS PeopleByCityAndLastName ...
</create>
<drop>
DROP STATISTICS PeopleByCityAndLastName
</drop>
<dialect-scope name="NHibernate.Dialect.OracleDialect"/>
<dialect-scope name="NHibernate.Dialect.Oracle9Dialect"/>
</database-object>
As you can see, this allows us to...
NHibernate Mapping - Concurrency
NHibernate has several concurrency models that you can use: None Optimistic Dirty All Versioned Numeric Timestamp DB timestamp Pessimistic ...
NHibernate Mapping - <set/>
And now it is time to go to the <set/> and explore it. Most of the collections in NHibernate follow much the same rules, so I am not going to go over them in details: <set
name="propertyName" (1)
table="table_name" ...
NHibernate Mapping - <dynamic-component/>
Like the <component/> mapping, <dynamic-component/> allows us to treat parts of the entity table in a special way. In this case, it allow us to push properties from the mapping into a dictionary, instead of having to have the entity have properties for it. This is very useful when we need to build dynamically extended entities, where the client can add columns on the fly. Let us take this entity as an example: And this table: Where we want to have the SSN accessible from our entity, but...
NHibernate Mapping - <many-to-one/>
Next up for inspection is the <many-to-one/> element. This element is defined as: <many-to-one
name="PropertyName" (1)
column="column_name" (2)
...
NHibernate Mapping - <component/>
<component/> is an interesting feature of NHibernate, which map more or less directly into the notion of a Value Type in DDD. This is a way to create an object model with higher granularity than the physical data model. For example, let us take the following table: And this object model: They are quite different, where the physical data model put all the data in a single table, we want to treat them in our object model as two separate classes. This is where <component/> comes into play: <class name="Person"
table="People">
<id...
NHibernate Mapping - <property/>
I am going to post a few things about NHibernate, going in depth into seemingly understood mapping. We will start with the most basic of them all: <property/> <property
name="propertyName" (1)
column="column_name" (2)
type="typename" ...
NH-1711 – Inappropriate error handling with NH 2.1 Alpha 1 when distributed transaction fails can cause application crashes
The actual problem has been fixed and it will be part of NH 2.1 Alpha 2. That is why we call them alphas, after all :-) The actual bug is pretty convulsed mess, to be frank. And it is no wonder that it slipped by me. Yes, I am the one responsible for that, so I guess I am making excuses. Let me tell you about the actual scenario. When you are using NHibernate 2.1 Alpha 1 (it does not affect NHibernate 2.0 or 2.0.1) with a System.Transaction.Transaction, there is a slightly different code path that we have to...
NHibernate: Avoid identity generator when possible
Before I start, I wanted to explain that NHibernate fully support the identity generator, and you can work with it easily and without pain. There are, however, implications of using the identity generator in your system. Tuna does a great job in detailing them. The most common issue that you’ll run into is that identity breaks the notion of unit of work. When we use an identity, we have to insert the value to the database as soon as we get it, instead of deferring to a later time. It also render batching useless. And, just to put...
NHibernate HQL AST Parser
Steve from iMeta has been doing a lot of work on the HQL AST Parser. For a long time, that has been a really troublesome pain point for us, since this is a prerequisite for a lot of other features. It is also one of two parts of NHibernate that really need significant refactoring because the way they are built right now make it hard to do stuff (the second being the semantic model for the mapping, which the Fluent NHibernate guys are working on). Just to give you two features that should make you drool which depends on...
Core NHibernate: Persistence with NHibernate
I can't believe that I didn't mention this before. I am partnering with Skills Matter to create a course about using NHibernate.
You can see the full details here.
The first run is in London in May, followed by Norway in June and London again in August. After that I stopped tracking, but it is very frequent.
This is a three days course that is meant for developers who want to get into NHibernate. I am going to assume zero NHibernate knowledge and take you to the spot where you can build NHibernate applications on your own.
The REALLY long way to query with NHibernate
I am doing some work on NHibernate, mostly rediscovering how things works. It is quite amazing how those things work, to tell you the truth. A few days ago I had a conversation about the NH source and I made three rapid discoveries that reduce the complexity of a feature by three orders of magnitude. The code that I am showing is how NHibernate manages its queries internally (well, one way of doing that). This is internal information, so not only you would never do that, but you canot even do that. ...
NH Prof documentation: Transaction and the second level cache
Another implication of not using explicit transactions with NHibernate is related ot the use of the second level cache. NHibernate goes to great lengths in order to ensure that the 2nd level cache shows a consistent view of the database. In order to do that it is defering all 2nd level cache updates to the transaction commit. In that way, we can be sure that the data in the 2nd level cache is the one committed to the database. Forgoing the use of explicit transactions has the effect of nulling the 2nd level cache. Here is an example...
NH Prof Alerts: Too many database calls per session
This is a bit from the docs for NH Prof, which I am sharing in order to get some peer review.
One of the most expensive operations that we can do in our applications is to make a remote call. Going beyond our own process is an extremely expensive operation. Going beyond the local machine is more expensive yet again.
Calling the database, whatever to query or to write, is a remote call and we want to reduce the number of remote calls as much as possible. This warning is being raised when the profiler notice that a single session is...
NH Prof Alerts: Excessive number of rows returned
This is a bit from the docs for NH Prof, which I am sharing in order to get some peer review. The excessive number of rows returned is a warning that is being generated from the profiler when... a query is returning a large number of rows. The simplest scenario is that we simply loaded all the rows in a large table, using something like this code: session.CreateCriteria(typeof(Order))
.List<User>();
This is a common mistake when you are binding to a UI component (such as a grid) that perform its own paging. This is a problem is several levels:
We tend to want...
NH Prof Alerts: Unbounded result set
This is a bit from the docs for NH Prof, which I am sharing in order to get some peer review. Unbounded result set is perform a query without explicitly limiting the number of returned result (using SetMaxResults() with NHibernate, or using TOP or LIMIT clauses in the SQL). Usually, this means that the application is assuming that a query will only return a few records. That works well in development and testing, but it is a time bomb in production. The query suddenly starts returning thousands upon thousands of rows and in some cases, it is...
NH Prof Alerts: Use of implicit transactions is discouraged
This is a bit from the docs for NH Prof, which I am sharing in order to get some peer review. A common mistake when using a database is that we should use only transactions to orchestrate several write statements. Every operation that the database is doing is done inside a transaction. This include both queries and writes ( update, insert, delete ). When we don't define our own transactions, we fall back into implicit transaction mode, in which every statement to the database run in its own transaction, resulting in a higher performance cost (database time to build...
NH Prof Alerts: Select N + 1
This is a bit from the docs for NH Prof, which I am sharing in order to get some peer review. Select N+1 is a data access anti pattern, in which we are accessing the database in one of the least optimal ways. Let us take a look at a code sample, and then discuss what is going on. I want to show the user all the comments from all the posts, so they can delete all the nasty comments. The naןve implementation would be something like: // SELECT * FROM Posts
foreach (Post post in session.CreateQuery("from Post").List())
{
...
Fluent NHibernate
A while ago I mentioned that as it stood at the time, I didn't see any major benefits for the Fluent NHibernate and that you might as well use the XML directly. What I wanted is NHibernate auto mapper. Couple of days ago I had the chance to take a look at Fluent NHibernate again. What I saw was almost exactly the dream that I had in mind. Here is my NHibernate mapping configuration for the whole application: public virtual void ConfigureNHibernate(Configuration configuration)
{
var model = new AutoPersistenceModel
{
...
NH Prof: Getting to zero friction
Here is a new (passing) integration test in the NHibernate Profiler:
Just to give you an idea, here is the implementation of this rule, which has to be one of the more complex ones that we have at the moment, because the data for it comes from several sources, so we need to actually execute the logic in an event, instead of directly.
public class TooManyRowsReturnedPerQuery : IStatementProcessor{ private ProfilerConfiguration configuration; public TooManyRowsReturnedPerQuery(ProfilerConfiguration configuration) { this.configuration = configuration; } ...
NH Prof: A moment in time
I just had a major moment in using NH Prof.
I run into a problem with NHibernate and was able to use the NH Profiler in order to figure out what the problem was.
Wow!
NHProf: What is the role of the DBA?
I am now discussing what sort of reports we want to give the DBA from the NHibernate Profiler. My first thought was just to give the DBA a list of the statements that the application has executed and the number of times they were repeated. That should allow him to get enough information to use his own tools to optimize the application physical data structure.
What do you think? Is this a good scenario?
What other scenarios can you see for NH Prof in the hands of the DBA?
NHProf: The stack is not as simple as you wish it to be
One of the nicest features that NH Prof has to offer is this, allowing you to go from the query issued to the database directly to the line of code that caused this query to be generated.
A few days ago I posted that you can either build something in one day, or in three months, but nothing much in the middle. The proof of concept that convinced me that I can build NH Prof was written during a single evening, along with two pints of Guinness. The overall concept that I have now is drastically different, but it is...
Solving the Select N+1 Problem
Note, I am currently writing the NH Prof documentation, so you are probably going to get quite a bit of NHibernate tidbits over the next few days. I want to show the user all the comments from all the posts, so they can delete all the nasty comments. The naןve implementation would be something like:foreach (Post post in session.CreateQuery("from Post").List()) // SELECT * FROM Posts
{
foreach (Comment comment in post.Comments) //lazy loading of comments list causes: SELECT * FROM Comments where PostId = @p0
{
//print comment...
...
NH Prof: Configuration Story
I think that I mentioned that NHibernate Profiler is working mostly by doing some smarts on top of the log output from NHibernate. That is not exactly the case, but that is close enough. The problem with working through the logs is that there are roughly 30 lines of XML that you need to deal with in order to manage this properly.
The first time I sent this to anyone else, he run into problems with the configuration because of very subtle issues. For a while now, I had a ticket saying that I need to document what the failure...
Setting expectations straight
I am currently working on getting a beta version of NH Prof out, but I run into a problem. There are several features that I intend to put into the release version that I didn't have the time to actually put it. Those are usually features that are good to have, but not necessarily important for the actual function of the tool. One of them is saving & loading the captured data. Currently, I am working on more important things than dealing with this, so I didn't implement this. However, I do want to make it clear that it...
NH Prof: A testing story
Remember that I mentioned the difference about working and production quality?
One of the things that separate the two that in production quality software, you don't need to know which buttons not to push. Here is a simple example. For a while now, if you tried to bring up two instances of NH Prof, the second one would crash. That wasn't something that you really want to show the users. Today I got back to doing NH Prof stuff, getting it ready for public beta, and I decided that the first thing to do was to tackle this easy feature.
Doing...
On NHibernate Quality
A while ago Patrick Smacchia posted an analyses of NHibernate 2.0 in NDepends. Go read it, it is interesting, not only because it gives an insight about how to utilize NDepends, but also as a good indication of problematic areas inside NHibernate. The NHibernate code base is aimed at solving a very complex problem, and I will be the first to admit that there are a lot of improvements that I would be delighted to do if I had infinite time to do so. In fact, some places of the code annoy me to the point where I make a...
The NHibernate Community
In response to Davy's post about the rise of interesting in NHibernate,I decided to run the numbers. Nine months ago we created the NHibernate Users, which has taken off quite nicely, with over thousand members and a very active community. For that matter, the stats for NHibernate downloads are quite nice as well. The dip just toward the end is just before we released NHibernate 2.0. Awesome!
Advance NHibernate Workshop Video
Two and a half hour of in depth NHibernate, from Kaizen Conf. You can get it here. I would really appreciate your comments about that. You can also see the NH Prof shown there, and its capabilities at the time (it got a few more since).
How NHibernate forced me to OO design
At some point of my code, I had this method. Remember, this is spike code, so I didn't care for breaking things like encapsulation or getting ugly code. In essence, the code above is breaking encapsulation and stomps all over DRY and Liskov substitution principle. It worked for a while, then it stopped. The reason that it stopped is that I started passing it lazy instances. And a lazy instance is a proxy, which is neither an ImageItem or HtmlItem. So now ContentItem has the following: As an aside, notice the RecordApperances method. That is the...
NH Prof Deep Dive: The Integration Test Architecture
I am getting a lot of requests to explore the actual innards of the NH Prof. I find it surprising, because I didn't think that people would actually be interested in that aspect of the tool.
But since interest was expressed, I'll do my best to satisfy the curiosity.The first topic to discuss is the integration test architecture. One of the things that the profiler is doing is to capture data from a remote process, and I wanted my integration tests to be able to test that scenario, which exposes me to things like synchronization issues, cross process communication and (not...
An NH Prof Bug Story: Why integration is tricky
Today I found out that NH Prof doesn't work with ASP.Net MVC applications. If you would have asked me, I would have sworn any oath you care to name that it would. And even after seeing the problem with my own eyes, it too me a while to track it down.
To make a long story short. Somewhere deep in the bowels of NH Prof, I made the assumption that a method is always contained in a type. I am pretty familiar with the way that the CLR works, and it seemed like a pretty reasonable assumption to make. In fact,...
NH Prof: A guided tour
NH Prof has reached the level in which I can actually talk about the features that it has in more than abstract terms. There is still a big feature area that I want to cover (which should be a nice surprise), but the basics are there, and today I had ample proof that it is maturing just nicely. I was able to deal with quite a few of the remaining tasks by applying check listing. Basically, to do X, I had to do A,B & C. Trivially simple, and quite satisfying.
Test coverage went back up to over 90% on...
Developing Linq to NHibernate
I have been thinking about this for a while now. Linq to NHibernate requires two to three months of full time development work in order to get to a really good usable state. The problem is that we don't have anyone working on that full time. Considering the nature of OSS, this is not surprising, but I would like to change that if I can.
I am trying to getting sponsorship from several companies that are willing to pay for the development of Linq for NHibernate. The details are very simple, if I get enough companies interested in this to dedicate...
Kazien Conf Workshops
Yesterday I gave two workshops, Advanced NHibernate and Building DSL with Boo. I finished the day absolutely crushed, but I think they went very well.
Both were recorded, although I am not sure when they will be online.
Ryan Kelley has a blow by blow description of the NHibernate talk, and you can get the code for that here:
https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/SampleApplications/ORM+=2/
I'll post the code for the DSL talk shortly afterward.
I got some really positive feedback about the NHibernate Profiler, and I am very interested in demoing that and getting additional feedback when the real conference starts.
NH Prof: Teaser
If you want to learn more, come to my Advanced NHibernate talk tomorrow.
This time, this is literally a snapshot of the application as it is running, and it is showing most of the surface level functionality that exists at the moment in the application.
Oh, and all the kudos for the look and feel goes to Christopher and Rob, who make it looks so easy.
NH Prof: How to detect SELECT N + 1
One of the things that the NHibernate Profiler is going to do is to inspect your NHibernate usage and suggest improvements to them.
Since I consider this to be a pretty important capability, I wanted to stream line the process as much as possible.
Here is how I detect this now:
It is not perfect, but it is pretty close.
A messaging problem: Order in the bus
In NH Prof, I have structured the application around the idea of message passing. I am not yet in the erlang world (which requires a framework that would keep hold of the state), but I am nearer than before.
The back end of the profiler is listening to the event streams generated by NHibernate. We get things like:
Session opened on thread #1
SQL Executed on thread #1
SELECT * FROM Customers
...
NHProf: Logging interception
One of the goals that I set for myself with the NHibernate Profiler is to be able to run on unmodified NHibernate 2.0. The way that I do that is by intercepting and parsing the log stream from NHibernate.
NHibernate logging is extremely rich and detailed, so anything I wanted to do so far was possible. I am pretty sure that there would come a time when a feature would require more invasive approaches, running profiler code in the client application to gather more information, but for now this is enough.
I did run into several problems with logging interception. Ideally,...
Making the complex trivial: Rich Domain Querying
It is an extremely common issue and I talked about it in the past quite a few times. I have learned a lot since then, however, and I want to show you can create rich, complex, querying support with very little effort. We will start with the following model: And see how we can query it. We start by defining search filters, classes that look more or less like our domain. Here is a simple example: public abstract class AbstractSearchFilter
{
protected IList<Action<DetachedCriteria>> actions = new List<Action<DetachedCriteria>>();
public void Apply(DetachedCriteria dc)
{
foreach(var action in actions)
{
action(dc);
}
}
}
public class PostSearchFilter : AbstractSearchFilter
{
private string title;
public string...
A bug story
I run into a bug today with the way NHibernate dealt with order clauses. In particular, it can only happen if you are: Use parameters in the order clause Using SQL Server 2005 Using a limit clause If you met all three conditions, you would run into a whole host of problems (in particular, NH-1527 and NH-1528). They are all fixed now, and I am writing this post as the build run. The underlying issue is that SQL Server 2005 syntax for paging is broken, badly. Let us take the this statement: SELECT THIS_.ID ...
NHProf: Another milestone
It is by no means the final UI, it was just thrown together by me in about half an hour, just to show how things are working.
I am also using it now to track what is going on in an application that I am working on.
NHProf: Alive! It is alive!
I just finished writing the final test for the basic functionality that I want for NHibernate Profiler:
[Test] public void SelectBlogById() { ExecuteScenarioInDifferentProcess<SelectBlogByIdUsingCriteria>(); StatementModel selectBlogById = observer.Model.Sessions.First() .Statements.First(); const string expected...
Sins of Omissions
Joel Splosky's latest column talks about Sins of Commissions has a lot of good information in it. In particular: There's a great book on the subject by Harvard Business School professor Robert Austin -- Measuring and Managing Performance in Organizations. The book's central thesis is fairly simple: When you try to measure people's performance, you have to take into account how they are going to react. Inevitably, people will figure out how to get the number you want at the expense of what you are not measuring, including things you can't measure, such as morale and customer goodwill. Where...
NHibernate & Static Proxies
I decided to take a look at what I would take to implement static proxies (via Post Sharp) in NHibernate. The following is my implementation log. 09:30 PM - Started to work on post sharp interceptors for NHibernate 09:35 PM - Needs to learn how I can implement additional interfaces with PostSharp. 10:00 PM - Implemented ICollection<T> wrapping for entities 10:35 PM - Proxy Factory Factory can now control proxy validation 11:15 PM - Modified NHibernate to accept static proxies 11:28 PM - Saving Works 11:35 PM - Deleting Works 11:50 PM - Rethought the whole approach and implemented...
How to build an application
I am currently working (well, sort of, more playing around) on the NHibernate Profiler. I thought that this would be a good time to describe how I approach most development tasks. I don't actually have the time/strength to start serious development effort, but I have the time to do a lot of spikes, and to think about architecture. If I decide to spend the time making this happen, I'll post more about how it works. I started with a spike about extracting the actual data from NHibernate. My target goal is being able to profile NHibernate 2.0...
The NHibernate Profiler
This is speculative at the moment, just to be clear.
I am thinking about creating a profiler for NHibernate. This came out of the common need to actually get a good view about what is going on with NHibernate.
This is intended to be a commercial project.
I have a feature set in mind, but I would rather hear from you if you think that it is a tool that you would use (and buy) and what kind of features do you expect such a tool to have?
And, to forestall the nitpickers, I am well aware of SQL Profiler.
NHibernate 2.0 and Linq
Linq for NHibernate is not part of the 2.0 release. Linq support is planned for the 2.1 release. That said, we have been getting a lot of questions about that. The technical reasons are not really interesting, but suffice to say that to provide good Linq support we also need to modify NHibernate slightly. Those changes happens on the trunk, which is what Linq for NHibernate is following. However, due to all the questions that we got, I wanted to point out that Daniel Guenter has back ported the current version of Linq to NHibernate to Nhibernate...
SQL Server 2008 Table Value Parameters and NHibernate
I just took a look at how this feature is exposed. I really wants this feature. I hit the 2,100 parameters limit of SQL Server too many times in the past, always when I had to do some large IN queries. So, I was very happy to hear about that feature, but I didn't really take a look until now. Unfortunately, the way they are implemented requires a hard reference to them. You have to create the type in the server, and then you have to reference it by name. Annoying, to say the least, and it looks like...
NHibernate 2.0 Wiki
NHibernate 2.0 Wiki can be found here. This wiki already includes the entire NHibernate documentation, so you can head there and start learning. Have fun...
NHibernate 2.0 Final is out!
Guys, gals and its. I am overjoyed to tell you that NHibernate 2.0 has been released. You can get it directly from the download page. I would like to thank to the NHibernate project lead, Fabio Maulo, for doing such an awesome amount of work, and getting this out. Thanks, Fabio. I am not going to list all the features, suffice to say that we are now in a comparable position to Hibernate 3.2. Have fun!
On Fluent NHibernate
There has been some noise lately about Fluent NHibernte. This gives you a fluent interface to configure NHibernate mapping. I don't really see the point, frankly. Fluent NHibernate, at least in its current stage, requires a mapping class per entity. At this point, I might as well use the XML again. In general, anything that requires me to touch two places to make one change is suspect. That is part of the reason that I like ActiveRecord, the change is highly localized. NHibernate's XML serve a very different purpose, it is explicitly designed to separate the persistence concern...
NHibernate Worst Practice - SQL
The question just came up in the NHibernate dev list, and I wanted to be as clear about this as possible.
If you can at all avoid it, do so. The use of SQL in NHibernate should be strongly discouraged. It is there to give you the ability to use the proprietary features of your database, and as a way to avoid the abstraction if you really need that.
The problem is when people are using that for things that they really shouldn't, like complex queries that they know how to express in SQL but not using NHibernate, so they drop to...
Entities dependencies best practices
The question came up in the ALT.Net list, and it is fairly common in the DDD circles as well. I have an User with Email address, which I want to keep encrypted in the database, but visible to the application. How do I handle this scenario in the entity? We can do it in our service layer, and encrypt / decrypt that outside the entity, but that has two issues. It couple the entity to the service and it means that we can forget to encrypt the email at some point.It also smells. ...
Impedance Mismatch and System Evolution
Greg Young is talking about the Impedance Mismatch, replying to Stephen Fortes post about Impedance Mismatch from a while back. Greg and I have a slightly different views regarding the details of many of the things he is talking about, but we are in agreement overall. You might say we take different approaches to the problem, but with the same overall direction. What I would like to talk about in this post is specifically this statement from Stephen: My first problem with ORMs in general is that they force you into a "objects...
How to review NHibernate application
A few hours ago I completed a code review of an application using NHibernate. This is not the first time I am doing such a thing, of course, and I noticed that there are quite a few areas where I tend to have comments in such code reviews. The following is based on several such code bases that I went through, and contains a partial list of things that you need to watch for. Mapping The recommended practice is to have each mapping file contain a single class. Having a single mapping file contain...
ADO.Net Data Services with NHibernate
Shawn Wildermuth has bridged the gap between the two, implementing IUpdatable on top of Linq to NHibernate. This means that you can now expose your NHibernate domain model as a set of REST services. This functionality is now included with Linq for NHibernate. Thanks Shawn! There is a live sample here: http://www.silverlightdata.com/Simple/NHibernate.aspx Or you can hit the URLs directly and see what kind of formatting it has: http://www.silverlightdata.com/Simple/HibProducts.svc/Products http://www.silverlightdata.com/Simple/HibProducts.svc/Products(1) http://www.silverlightdata.com/Simple/HibProducts.svc/Products(1)/Category From a technological perspective, I think this is awesome. However, there are architectural issues with...
Integrating NHibernate and Active Record
On the face of it, this is a nonsense post. What do I mean, integrating NHibernate and Active Record? Active Record is based on NHibernate, after all. What kind of integration you need? Well, sometimes you want to be able to use NHibernate entities in an Active Record project. And that tended to be very hard. (The other way was extremely easy, just tell Active Record to generate the mapping and move from there.) A week or so ago I added support for doing it the other way around, of adding POCO NHibernate entities into the ActiveRecord model. ...
NHibernate 2.0 Beta 1 Released
NHibernate 2.0.0.Beta1 is released today. It is comparable to Hibernate 3.2 in terms of features. Get the bits while they are hot.
Pluggable Domain Model
Rhino Security is a good example of a pluggable domain model, in which we can plug some functionality into different and varied domains. Here is an interesting demo to show how you can use it. public static void DemoUsingCustomerCareModule<TCustomer>(string schema)
where TCustomer : ICustomer, new()
{
Configuration cfg = new Configuration()
.Configure("hibernate.cfg.xml")
.AddAssembly(typeof(Lead).Assembly)
.AddAssembly(typeof(TCustomer).Assembly);
cfg.MapManyToOne<ICustomer, TCustomer>();
cfg.SetSchema(schema);
new SchemaExport(cfg).Execute(true,...
Dynamic Mapping with NHibernate
A while ago I posted how to handle dynamic mapping with Active Record, it was incredibly easy to do, because Active Record has a lot of smarts internally, and output the XML, on top of which NHibernate adds quite a bit of convention over configuration as well. Doing the same using NHibernate directly is possible, but a bit long winded. Here is the sample code, which link all the Employee properties to the correct entity: Configuration cfg = new Configuration()
.AddAssembly(typeof (Employee).Assembly)
.AddAssembly(typeof(ScheduledTask).Assembly);
Mappings mappings = cfg.CreateMappings();
foreach (PersistentClass persistentClass in mappings.Classes)
{
...
The NHibernate FAQ Blog
With the advent of the NHibernate Users list, we also needed a place for frequent questions. While the Hibernate's site already has a FAQ in place, I feel that a blog is a better medium for this. Therefor, welcome the NHibernate FAQ Blog, which Gabriel Schenker and Tom Opgenorth has agreed to maintained. There are several good articles there already. Covering anything from setting up query logging to correct handling of entity equality. Subscribed.
NHibernate 2.0 Alpha is out!
It gives me great pleasure to announce that NHiberante 2.0 Alpha 1 was released last night and can be downloaded from this location. We call this alpha, but many of us are using this in production, so we are really certain in its stability. The reason that this is an alpha is that we have made a lot of changes in the last nine months (since the last release), and we want to get more real world experience before we ship this. Recent estimates are of about 100,000 lines of code has changed since the last...
Adaptive Domain Models with Rhino Commons
Udi Dahan has been talking about this for a while now. As usual, he makes sense, but I am working in different enough context that it takes time to assimilate it. At any rate, we have been talking about this for a few days, and I finally sat down and decided that I really need to look at it with code. The result of that experiment is that I like this approach, but am still not 100% sold. The first idea is that we need to decouple the service layer from our domain implementation. But why? The...
NHibernate users mailing list
Bil Simser has create the NHibernate Users mailing list, which you can access here: http://groups.google.com/group/nhusers I find mailing lists much easier to work with than forums, so I am really happy about it.
I think my brain just fried
I am working on ICriterion and IProjection at the moment, making each understand each other. It is working very well, and I really like the ability to just go in and make a drastic change. The problem is the scope of the change. I have had to touch pretty much all of the NHibernate.Expression in the last two days. Just to give you an idea, here is the most recent comment. Damn I am glad that I have tests there.
Linq for NHibernate Adventures
So for the last few hours I have been getting back into the Linq for NHibernate project, after having left it for far too long. I am beginning to think that building a Linq provider might not have been the best way to learn C# 3.0, but never mind that now. It is with great pride that I can tell you that the following query now works: from e in db.Employeesselect new { Name = e.FirstName + " " + e.LastName, Phone = e.HomePhone } Why is this trivial query important? Well, it is important because about a year ago...
NHibernate Queries: Find all users that are members of the same blogs as this user
Let us assume that we have the following model: User n:m -> Blogs n:m -> Users Given a user, how would you find all the users that are members of all the blogs that the user is a member of? Turn out that NHibernate makes it very easy: DetachedCriteria usersForSameBlog = DetachedCriteria.For<User>()
.Add(Expression.IdEq(userId))
.CreateCriteria("Blogs")
.CreateCriteria("Users", "user")
.SetProjection(Projections.Id());
session.CreateCriteria(typeof(User))
.Add(Subqueries.PropertyIn("id", usersForSameBlog))
.List();
And the resulting SQL is:
SELECT this_.Id AS Id5_0_,
this_.Password AS Password5_0_,
this_.Username AS Username5_0_,
this_.Email AS Email5_0_,
this_.CreatedAt AS CreatedAt5_0_,
this_.Bio AS Bio5_0_
FROM Users this_
WHERE this_.Id IN (SELECT this_0_.Id AS y0_
FROM Users this_0_
INNER JOIN UsersBlogs blogs4_
ON this_0_.Id...
Future Query Of implemented
It took very little time to actually make this work. I knew there was a reason liked my stack, it is flexible and easy to work with. You can check the implementation here, it is about 100 lines of code. And the test for it:FutureQueryOf<Parent> futureQueryOfParents = new FutureQueryOf<Parent>(DetachedCriteria.For<Parent>());
FutureQueryOf<Child> futureQueryOfChildren = new FutureQueryOf<Child>(DetachedCriteria.For<Child>());
Assert.AreEqual(0, futureQueryOfParents.Results.Count);
//This also kills the database, because we use an in
// memory one ,so we ensure that the code is not
// executing a second query
CurrentContext.DisposeUnitOfWork();
Assert.AreEqual(0, futureQueryOfChildren.Results.Count);
Future<TNHibernateQuery>
A while ago I added query batching support to NHibernate, so you can execute multiply queries to the database in a single roundtrip. That was well and good, except that you need to know, in advance, what you want to batch. This is often the case, but not nearly enough. Fairly often, I want disparate actions that would be batched together. It just occurred to me that this is entirely possible to do. In my Rhino Igloo project, I have a lot of places where I have code very similar to this (except it can go for quite a while):...
NHibernate and the second level cache tips
I have been tearing my hair our today, because I couldn't figure out why something that should have worked didn't ( second level caching , obviously ). Along the way, I found out several things that you should be aware of. First of all, let us talk about what the feature is, shall we? NHibernate is design as an enterprise OR/M product, and as such, it has very good support for running in web farms scenarios. This support include running along side with distributed caches, including immediate farm wide updates. NHibernate goes to great lengths to ensure cache consistency in...
Dealing with hierarchical structures in databases
I have a very simple requirement, I need to create a hierarchy of users' groups. So you can do something like: Administrators DBA SQLite DBA If you are a member of SQLite DBA group, you are implicitly a member of the Administrators group. In the database, it is trivial to model this: Except that then we run into the problem of dealing with the hierarchy. We can't really ask questions that involve more than one level of the hierarchy easily. Some databases has support for hierarchical operators, but that is different from one database to...
And in NHibernate Land
This is just an update. Fabio has been porting large swathes of Hibernate 3.2, Paul is dealing with the continued port of Hibernate Search while Dario has focused on porting Hibernate Validator. He has also just started to port Hibernate Shards, which is going to make things very interesting indeed. Me? I am sitting in the corner, admiring the work and occasionally shouting hurray!
Creating Partial Domain Models
Here is an interesting problem. I want to package a domain model with specific functionality, but I don't want to constrain the model users of this functionality will use. For example, let us take security systems and the User entity. I have yet to see any two projects that had identical users entities. Now, the concept of a user in a security system is pretty important, I would say. But no important enough that I would want to force my idea about what a user looks like on an innocent domain model. Problem, right? Now really. We can use the...
Active Record: Mapping Rewriting
One of the really nice things about using the NHibernate / Active Record stack is that there are so many extensions points. One of the more fun things is the ability to do runtime modifications of the mapping. Here is a simple example:ActiveRecordStarter.ModelsCreated+=delegate(ActiveRecordModelCollection models, IConfigurationSource source)
{
foreach (ActiveRecordModel model in models)
{
if(model.Type == typeof(User))
{
model.ActiveRecordAtt.Table = "MyUsers";
}
...
NHiberante: Querying Many To Many associations using the Criteria API
Over a year ago I was asked how we can query a many to many association with NHibernate using the criteria API. At the time, that was not possible, but the question came up again recently, and I decided to give it another try. First, let us recall the sample domain model: Blog m:n Users 1:m Posts n:m Categories 1:m Comments And what we want to do, which is to find all Posts where this condition is met: Blog.Users include 'josh' and Categories includes 'Nhibernate' and a Comment.Author = 'ayende'. At the time, it wasn't possible to express this query using...
NHibernate and Generic Entities
Colin Jack has brought up the question of generic entities, which is something that I consider fairly odd use case. Generics are very useful, but not in the final entity layer (they are very useful as layer super type, though). First, let us understand what I am are talking about when I am thinking about generic entities: The generic entity that you see is ContactInformation<TContactInfoType>, and we want to use several specialized versions of that in our application. In this case, we have contact that can be either a string or a user. Here is an interesting tidbit,...
What is going on with NHibernate 2.0?
Well, I haven't wrote anything about that in a while, and I am scanning the change log right now, and it looks like a lot have been going on. Fabio Maulo has been going at it with gusto, and has ported several very big features, and I would like to take this opportunity to thank him for that. Karl Chu has been doing some really nice things as well, and deserve thanks as well. Awesome work, both of you. Me, I am sitting in the corner with slack jaw and watching the feature pile on top of each other. This...
The scary FooBarTest
I just made some edge case coverage for SQL 2005 Dialect in NHibernate, those edge cases required a wholly different approach, and took about three times as long as I thought they would. In the end, I got a working design that I liked, and then it was time to turn on the big guns, running the entire NHibernate test suite (1028 tests as the moment, in the core test project). That is fairly good in throwing all kind of weird poo at NHibernate, and ensuring that we can actually can withstand what real developer throw at us. I had four breaking...
Real World NHibernate: Reducing startup times for large amount of entities
The scenario that Christiaan Baes need to solve is reducing the startup time of a Win Forms application. The main issue here is that the initial load of the application should be fast, but in this case, we are feeding NHibernate about a hundred entities, so it take a few seconds to run them. I asked Christiaan to send me profiler results of the code, and it looked all right on his end, so it was time to look at NHibernate and see what she had to say about that. The test scenario was startup time for a thousands entities. I think that...
Specifying Specifications
Specification: An explicit statement of the required characteristics for a matching entity / object. Specifications are very useful concepts when you need to think about searches. They are useful because they seperate what you are searching from how you are searching. In the example to the right, we have a specification for a job opening. We can use it to search for matching job openings. But couldn't we do it directly? Yes we could, but then we would dealing with both what and how at the same time. Let us say that we want to search for an opening...
Querying Complexity
When it comes to building search screens, there really isn't something that I would rather use over NHibernate. I am just astounded at how I can slice a very complex scenario into very narrow & clear fashion: criteria.Add(Expression.Disjunction()
.Add(Expression.Disjunction()
.Add(Expression.Eq("City1.id", value))
.Add(Expression.Eq("City2.id", value))
.Add(Expression.Eq("City3.id", value))
.Add(Expression.Eq("City4.id", value))
)
.Add(Expression.Conjunction()
.Add(Expression.IsNull("City1.id"))
.Add(Expression.IsNull("City2.id"))
.Add(Expression.IsNull("City3.id"))
.Add(Expression.IsNull("City4.id"))
)
);cloned.Add(Expression.Disjunction()
.Add(Expression.In("PreferredArea1", ToArray(Areas)))
.Add(Expression.IsNull("PreferredArea1"))
);
cloned.Add(Expression.Disjunction()
.Add(Expression.In("PreferredArea2", ToArray(Areas)))
.Add(Expression.IsNull("PreferredArea2"))
);
Now imagine roughly 20 such cases, all of them can be added/removed dynamically... I am going to write a far longer post about the specification pattern and how it useful it is.
Update: Andrew reminded me that there are easier ways to do this, using operator overloading, let us take the first example and see how it goes:
criteria.Add(
(
Expression.Eq("City1.id", value) ||
Expression.Eq("City2.id",...
Commercial support for Castle Windsor, Castle MonoRail, NHibernate, etc
This post by Ben Scheirman is interesting. He points out that the MS.MVC stuff is targeted toward a different crowd than the one who is using MonoRail, it is targeted toward the corporate developers and the All-Microsoft Shops.
The question of support has been raised again, and it prompted this post. It seems that there isn't a lot of awareness that there are commercial support options for those tools.
Castle Stronghold is the obvious place for commercial support for Castle.
JBoss / RedHat are offering commercial support for NHibernate. JBoss no longer support NHibernate.
...
Real World NHibernate Screen Cast: Planning
Did you noticed? Most of the guidance about tools are about how to get you started, but much more light on how to get going in the face of real world scenarios. NHibernate is no exception in this regard, so you can find a lot of information about getting started, but far less on how to actually deal with it. So this is a official solicitation of interesting NHibernate issues that you have run into. When I first thought about it, I figured out that querying was where most of the interest lay (that is certainly where I mostly sit back...
How to get NHibernate to work with PK values generated by a trigger?
Well, the correct answer is to use a <generator type="select">, but that hasn't been ported to NHinbernate yet, so a quick & dirty solution may be this piece of code, that I just wrote in Notepad and I have no idea if it really works :-) public class MyOracleDialect : OracleDialect
{
public override bool SupportsIdentityColumns
{
get
{
return true;
}
}
public override string GetIdentitySelectString(string identityColumn, string tableName)
{
return "select mySequnece_"+tableName+".currnetValue() from dual; ";
}
}
NHibernate – not all that glitters is gold
Manuel Abadia has some criticism on NHibernate that I wanted to respond to. First things first, though, it seems that I have been hasty in my response to a problem that Manuel reported, NH-1123. I really don't like it when other people do it to me, and I would like to apologize to Manuel for treating him in a manner I don't wish to be treated. As an aside, I have created a new bug on the JIRA, with a bit more focus on the underlying problem. This bug has now been fixed, and I would like to thank Manuel for (a) finding it, (b)...
NHibernate is female
I giving NHibernate instruction recently, and I am doing it in Techno-Hebrew, which means that I speak in Hebrew but all the technical terms are in English. It has some amusing side affects, and I find it simply hilarious when I hear someone else does it (Techno Hebrew/Arabic or Techno Hebrew/Russian are killers). At any rate, Hebrew is one of those languages where everything has a gender. Wind is female, and apple is male, etc. At about half way through the lesson, I found that I have kept referring to NHibernate as She. I have nothing further to add...
Slicing & Dicing Queries with NHibernate
This was how I started the day, interesting problem, and I like the solution:DetachedCriteria getMaxScanDateForScan = DetachedCriteria.For<ScanResult>()
.SetProjection(Projections.Max("ScanDate"))
.Add(Property.ForName("ScanUri").EqProperty("scan.Id"));
DetachedCriteria hasResults = DetachedCriteria.For<ScanResult>()
.SetProjection(Projections.Id())
.Add(Property.ForName("ScanUri").EqProperty("scan.Id"));
criteria
.CreateCriteria("Results", "result", JoinType.LeftOuterJoin)
.SetProjection(
Projections.ProjectionList()
.Add(Projections.Property("scan.Id"), "Id")
.Add(Projections.Property("scan.Uri"), "Uri")
.Add(Projections.Property("scan.DaysNotice"), "DaysNotice")
.Add(Projections.Property("scan.EnableScan"), "EnableScan")
.Add(Projections.Property("result.ScanDate"), "LastScan")
.Add(Projections.Property("result.Status"), "Status")
.Add(Projections.Property("result.Message"), "Message")
)
.Add(Expression.Disjunction()
.Add(Subqueries.PropertyEq("result.ScanDate", getMaxScanDateForScan))
.Add(Subqueries.NotExists(hasResults))
);
IList list = criteria
.GetExecutableCriteria(session)
.SetResultTransformer(new AliasToBeanResultTransformer(typeof (ScanURIReport)))
.List();
Lazy Property Loading In NHibernate
Well, I am not going to give the implementation here, but here are some notes for the implementation. What you basically need is actually quite simple. Start with a partial query, as shown here. Instead of returning the object, return a proxy to the object, that is aware of which properties were loaded. When a property is accessed that is not in the loaded properties list, do the following: Load the real object using NHibernate. Copy the existing values from the current object to the newly loaded one. (Preserving state) Redirect all calls to the newly loaded object....
Partial Object Queries With NHibernate
Aaron still wants partial object queries, so I set up to build them using NHibernate. Here is the implementation, notice that this query will result in a list of Blog instances, but the select will only include their titles & subtitles. using (ISession session = sessionFactory.OpenSession())
{
TupleToPropertyResultTransformer transformer =
new TupleToPropertyResultTransformer(typeof(Blog),"Title", "Subtitle");
IList list = session.CreateQuery("select b.Title, b.Subtitle from Blog b")
.SetResultTransformer(transformer)
.List();
foreach (Blog b in list)
{
System.Console.WriteLine("Blog: {0} - {1}", b.Title, b.Subtitle);
}
}
But where does TupleToPropertyResultTransformer comes from, well, that is where the magic comes in, here is my implementation for it:
public class TupleToPropertyResultTransformer : IResultTransformer
{
private Type result;
private PropertyInfo[] properties;
public TupleToPropertyResultTransformer(Type result, params string[] names)
{
this.result...
Optimizing NHibernate
Aaron (Eleutian) is talking about some issues that he has with optimizing with NHibernate. So in short, I feel NHibernate (and any ORM for that matter) needs the following features to really be optimization friendly: Lazy field initialization Querying for partial objects: select u(Username, Email) from User u Read-only queries that do not get flushed. Join qualifiers (on in T-SQL) Let me try to take this in order. Lazy Field Initialization: On the surface, it looks very good, because you can do something like: Customer customer = session.Load<Customer>(15);Console.Write(customer.Name); And the OR/M would generate...
NHibernate for SQL
Here is a little known fact, you can ask NHibernate to take any arbitrary result set from the database and turn it into an object.
return session.CreateSqlQuery(@"
select customer.Name as CustomerName,
count( case order.Type when 1 then 1 else 0 end ) as FastOrder,
count( case order.Type when 1 then 2 else 0 end ) as SlowOrder,
count( case order.Type when 1 then 3 else 0 end ) as AirMailOrder,
from Orders order join Customers customer
on order.Customer = customer.Id
group by customer.Name
")
.AddScalar("CustomerName", NHibernateUtil.String)
.AddScalar("FastOrder", NHibernateUtil.Int64)
.AddScalar("SlowOrder", NHibernateUtil.Int64)
.AddScalar("AirMailOrder", NHibernateUtil.Int64)
.SetResultTransformer(new AliasToBeanResultTransformer(typeof (CustomerOrderTypesCount)))
.List();
As you can probably imagine, this will return a list of CustomerOrderTypesCount objects, with...
HQL Parser: Progress
I still have recursive headache, but I think that I managed to grok how this works. To the point where I can now follow errors in the grammar and actually fix them. I was very surprised (pleasantly so) that the output from ANTLR is actually debuggable and make sense. At any rate, I now got this test to pass, which is very encouraging: [Test]
public void ComplexWhere_AlternativeCase()
{
Query q = Parse("from Customer c where 1 = (case c.Name when 'ayende' then 1 else 0 end)");
BinaryExpression expression = (BinaryExpression) q.WhereClause.Expression;
Assert.AreEqual(BinaryOperatorType.Eq, expression.Operator);
Assert.AreEqual("1", ((ConstantExpression) expression.Left).Value);
CaseExpression caseExpr = (CaseExpression) expression.Right;
Assert.AreEqual("c.Name", caseExpr.ConditionalExpression.ToString());
AlternativeWhenExpression whenClause = (AlternativeWhenExpression)...
Working with ANTLR: HQL Grammar
I am currently trying to build an ANTLR grammar for HQL. There is already an existing one for Hibernate 3, but that one is based on ANLTR 2.x and supports quite a bit more than NHibernate does at the moment (DML statements, for instance). After several failed attempts to port the grammar to ANTLR 3 and generate C# code out of it, I gave up and started building my own. I have read the ANTLR book not that long ago, so I ought to have a known what was in store for me. I didn't. I found out that this...
DevTech session: Storming Castle Windsor & NHibernate
I am announcing this a bit late, but I am going to give a talk about the Castle Winsdor & NHibernate on Thursday next week (03 July 2007).The anouncement has an amusing typo, I am afraid, which bring to mind some horrifying options The talk will be at DevTech, a conference that my company is arranging, so a lot of the people that I work with are going to give interesting talks. You can get more details here. Oh, and apparently I...
Answering Mats' Challenge
Mats Helander has a challenge for OR/M developers, and Mats should know, since he is behind NPersist.
Go for the post for details, but basically it is loading all Customer->Orders->OrderLines graph in 3 statements or less.
Because I am a sucker for challenges, I implemented it with ActiveRecord. In Mats' terms, the code is so simple it hurts, and yes, I cheated :-)
internal static IList<Customer> LoadCustomersOrdersAndOrderLines()
{
Customer[] customers = Customer.FindAll();
Order[] orders = Order.FindAll();
OrderLine[] orderLines = OrderLine.FindAll();
foreach (Customer customer in customers)
{
customer.Orders = new List<Order>();//avoid lazy load when adding
}
foreach (Order order in orders)
{
order.OrderLines = new List<OrderLine>();//avoid lazy load...
Case Sensitive Optimization
I am doing some optimization work lately, and I managed to take a page down to three DB requests per page load, but I couldn't get it to less than that, and it really annoyed me. The problem was that accessing a certain properly on an entity would cause a lazy load, even though I have explicitly told it to eagerly load that. That was... annoying. Eventually I got rid of all the "it can't be!" mentality and looked at what was going on, the problem was that I was looking for NHibernate bug. The problem was actually more subtle...
Dreaming in Code: Multi Linq
I was asked how we will approach the same Multi Query approach with Linq integration, here are some thoughts about it.var posts = from post in data.Posts
where post.User.Name == "Ayende"
orderby post.PublishedDate desc;
var postsCount = posts.Count();
posts.Skip(10).Take(15);
new LinqQueryBatch()
.Add(posts)
.Add(postsCount)
.Execute();//perform the query
foreach(Post p in posts)//no query
{
Console.WriteLine(p.ToString());
}
//no query
Console.WriteLine("Overall posts by Ayende: {0}", postsCount.Single() );
The LinqQueryBatch in this case doesn't need to pass delegates to process the results, it can modify the Linq Query directly, so trying to find the result will find the one that was already loaded...
Syntax: Multi Something
As I have already explained, I am doing a lot of work with NHibernate's MultiCriteria and MutliQuery. There are very powerful, but they are also mean that I am working at a level that has a lot of power, but a bit of a complex syntax. I want to improve that, but I am not sure what the best way to do it. Anything here is blog-code, meaning that I didn't even verified that it has valid syntax. It is just some ideas about how this can go, I am looking for feedback. The idea here is to have a...
NHibernate's Xml In
I wrote it because of a particular problem that I have run into, which is not something that I have heard much discussion about. In my application, I need to query the database about a certain data, and the best way to do that would be using an in query. For the purpose of discussion, I want to find all the customers associated with the current user. Unfortantely, I can't do something as simple as "Where.Customer.User == CurrentUser", because a customer may be associated to a user in many complex and interesting ways...
NHibernate Query Generator - More Collections Magic
I wouldn't have expected it to be this hard*, but it is alive! Here is the query: 1: User one = User.FindOne( 2: ...
Performance and Explicit Domain Models
Udi talks about limitations for DDD as a result of performance constraints. He says: Ayende and I had an email conversation that started with me asking what would happen if I added an Order to a Customer’s “Orders” collection, when that collection was lazy loaded. My question was whether the addition of an element would result in NHibernate hitting the database to fill that collection. His answer was a simple “yes”. In the case where a customer can have many (millions) of Orders, that’s just not a feasible solution. He then goes on to describe several solutions for the...
Debugging NHibernate
Today we had a problem with an NHibernate query that was failing which had quite stumped. Pulling the usual tricks didn't work, debugging NHibernate was problematic, since the failing query was damn complex, and I had no clear idea why this was failing. After a while, I decided that trying the top down approach will not work, and that I need more structure in finding out the issue. Did I mentioned that the query was complex? The object model is big as well, and the query managed to touch just about all of...
On SubSonic & NHibernate
I recently got this email, and the author has kindly given me permission to post the email and my response to it: At this moment, I will be suggesting to my project team in my company to use ORM, hopefully to make our software development faster especially on the data layer side. We use LLBLGen (the old one), and we really have plenty of stored procedures which were hard to maintain. I also noticed about subsonic today. I watched the videos and were impressed about it. 1) However I am not too clear about the difference between subsonic and nhibernate. It...
NHibernate Query Generator 1.9 is out!
Here are the goodies: Breaking change: I modified the way that NHQG accepts parameters, I am not using a non-hacky approach for this, but this means that you would need to modify any scripts that you have. Instead of positional parameters, you have to specify what the name of the parameters are, I think that it would be easier this way. Added AddOrder(), SetProjection() to QueryBuilder - patch from Ramon Kania Support for nested components - patch from Craig Neuwirt Stateless root for the query in case you want to really build it from scratch - that one is actually...
NHibernate Query Analyzer for NHibernate 1.2 GA
I am a bit late with this one, but here is a new version for NHibernate 1.2 GA. This also supports Castle Active Record, hopefully in a version neutral way. You can get it here, or admire the UI here: As an aside, I am thinking about adding Criteria Query functionality, since this is something that I use a lot. I am not sure yet what form this would take, at any rate it would involve runtime code generation, so that is complex (and sort of fun/pain). I am opened to ideas. Have fun...
Adaptive Fetching Strategies in ORMs
Aaron has a post about some wild ideas about OR/M fetching, specifically, auto-learning fetching strategies. The idea has merit, and the required technicalities are already inside NHibernate, I can imagine a proxy that talks to to fetching strategy to inform it about accessed properties, which would give it the information needed for the next time the same query is made. But, how do you correlate queries? I have "Repository<Salary>.FindAll(Where.Salary.Employee == CurrentEmployee);" in several places, in the "list employee salaries page" and in the "calculate tax" service. Each requires a different fetching strategy. Worse, I have this hiding in a method call...
Re: The OR/M Smackdown
Ted Neward responded to the comments in my post about the OR/M Smackdown. A few of the comments to my post had an unpleasant tinge to them with regard to Ted, and after listening (just today!) to the podcast, I have to say that I disagree with them. I think that the debate took an unforeseen approach (which may have made it less exciting to listen to) in that it didn't rehash all the old OR/M vs. SP debates*, but instead focused on stuff (that at least to me) that is not really discussed much. As a...
The little query that could
It looks likes I still have a lot to learn about NHibernate, today I took a foray into criteria's projections, which are new and exciting to me, but what excites me right now is this little puppy. It is not that the query is terribly complicated, it is that this is traversing six tables as easily as it can be. From the Multi Query reference, you can probably understand why I am excited, I need to get ~6 results sets for this to work, and it is looking like this is going to be very easy...
NHibernate & WCF
Just to reference a great article about using NHibernate & WCF, worth checking out.
NHibernate Tidbits: Serializing ICriteria
Quite a few parts of NHibernate are serializable. ISession and ICriteria are of particular interest to this post. Serializing the session (neccesiate that the entities are serializable, of course) is very useful for the Session-pre-conversation mode. But it is the criteria that I would like to talk about right now. Criteria in NHibernate is the OO interface for making queries. So, why is it important that it is serializable? Well, it opens up some interesting scenarios. Saved searches or reports are just one of many. I have used similar functionality in the past...
NHibernate Multi Criteria
A while ago I added Mutli Query to NHibernate, but I didn't have the time to add Multi Criteria capabilties in time for the 1.2 release. As it turn out, I managed to implement it about three weeks ago, and only now I had enough time to sit and document it. Just as a reminder, the end goal is being able to use NHibernate to send this query in a single roundtrip to the database: SELECT TOP 15 * FROM Customers
NHibernate one-to-one
I should start by saying that <one-to-one> is not a recommended approach, but the question came up in the Castle mailing list, and I set to investigate. There are scenarios where this is the only choice, but in general, prefer to avoid it. Here are our entities: [ActiveRecord("Users")] ...
Mean Fiddler: REST-style query service for NHibernate
Continuing with the theme of showing off and building clones of the Microsoft's demos in hours, Anders Norås has just posted Mean Fiddler, an implementation of REST API for NHibernate, similar to Microsoft's Astoria project. Nice work.
Converting an object collection to a DataSet
There are many tools that tends to work only with DataSets, the most often cases are reporting tools or data driven systems. I consider this an issue with the tool, usually, but this is a fact of line. Case in point, I want to display a report of customer objects, I say objects here because I retrieve them through an NHibernate query + business logic that can't really be done in a stored procedure. At the end, I get a collection of customer objects, and I need to pass that to a reporting tool...
NHibernate for Reporting...
Just finished writing some fairly complex reports. The reports are complex enough that I decided that it isn't worth my time to try to build a stored procedure to do it, and I simply used NHibernate to get the data. The simplest report had 14(!) parameters, but the main issue was handling security and running business logic as part of the report. (Specifically, a lot of date calculations). To be clear, I am talking about using NHibernate as a data source for a report, not generating the report itself. That is done with...
Bumbler: NHibernate Dynamic / Interactive Shell
After reading a bit about Jasper, I decided that I would like to see what it would take to build it with NHibernate and Boo. I am going to implement it and write the post at the same time, so you would get near real time documentation of the process. 18:05, decided that I want this syntax: ...
NHibernate 1.2 Released!
After about 6 months, we have a new stable release of NHibernate. The full details are here. I would strongly urge you to upgrade, but be aware that this is not a drop in replacement, there is a migration guide available. From experiance, it takes about a day to convert a reasonable size application to 1.2. Favorite new features: Filters - (I really wish that I had them when I started my previous project) ...
Remember what mommy told you...
Found on the wall in one of my clients (translation below): Liberally translated from Hebrew:Mommy said that you mustn't put Collections in the Session, otherwise Hibernate would beat you up. That had me cracking for quite a bit more than was polite.
Challange: Finding the missing piece
When comparing NHibernate to the Entity Framework, I found two places that the Entity Framework could do things that were difficult to do with NHibernate. One was multi table entities, that was already taken care of, thanks to a patch by Karl Chu. The second is parameterized projections. I will fix that if you can figure out what this means, and when you would like to use that.
Paged data + Count(*) with NHibernate: The really easy way!
Christian Maslen ping me about this article, which shows how to use NHibernate to execute multiply statements in a single round trip. Christian suggest a much neater solution: SELECT C.*, COUNT(*) OVER() AS TotalRows ...
Multi Table Entities in NHibernate
A while ago I posted about the ability to map n tables to a single entity in the Entity Framework. I didn't like it then, and I quoted from the Hibernate documentation that discourage this behavior:We consider it an essential element of good object model design that the object model be at least as granular as the relational model. If the original data modeller decided that certain columns should be split across two different tables, then there must have been some kind of conceptual justification for that. There is no reason not to also make that...
ORM and when query plans go bad
D. Mark Lindell has a few questions about sclaing ORM: How can dynamic SQL ORMs deal with the fact that your database server (a.k.a SQL Server) can decide at any point that it is going to use an alternate query plan. A simple index HINT on the join syntax can fix this problem but how is my ORM going to handle this? ...
Advance: Extending NHibernate Proxies
There was some interest in extending the way NHibernate deals with the entities, and I have just commited those changes into the trunk. Notice that since NHibernate 1.2.0 is at feature freeze right now, this will not be in 1.2.0 RTM, but at a later version. At any rate, let us see how we can extend NHibernate so it would offer automatic implementation for INotifyPropertyChanged. Some caveats: It works only for entities that have lazy loading enabled (the default for 1.2.0) which were retreived from NHibernate. You can see the...
Linq for NHibernate: Functions
Bobby Diaz is still producing some amazing stuff. The new addition is native support for SQL functions. Take a look at this code:DateTime date = new DateTime(1960, 1, 1); var query = ( from e in db.Employees where db.Methods.Year(e.BirthDate) >= date.Year && db.Methods.Len(e.FirstName) > 4 select e.FirstName ) .Aggregate(new StringBuilder(), (sb, name) => sb.Length > 0 ? sb.Append(", ").Append(name) : sb.Append(name)); Console.WriteLine("Birthdays after {0}:", date.ToString("yyyy")); Console.WriteLine(query); Check...
ORM:1, Hand Coding:0
Alexey has an interesting story about big cost saving (money, time, simpler architecture) NHibernate has enabled for his team. I recall doing an integration project once where I was able to move the database from an intermediatory SQL Server to DB2 on AS400 by changing a few lines in the configuration files (the client decided not to go with the approach, though, since it didn't fit their ESB plans).
Linq For NHibernate: More Implementation Details
Bobby Diaz did some more work recently, and has documented it here. Interesting reading...
NHibernate Search
I have just commited the full implementation of NHibernate Search. No documentation yet, but there is the Hibernate Search documentation, which matches nearly 1:1. You can get it from NHibernate trunk:svn co https://svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate.Search It probably won't be released with NHiberante 1.2, but it would work with it.
Visual Studio Designer for Active Record & NHibernate
Gökhan Altınören has just updated Active Writer, a designer for Active Record, and now for NHibernate as well. The bits are on Castle Contrib trunk
NHibernate Migration Guide: From 1.0 to 1.2
Billy McCafferty may have intended just to give a sample of how to move from NHibernate 1.0 + my NHibernate.Generics to NHibernate 1.2, but his post is actually a very good guide about migrating in general from 1.0 to 1.2. The part that you really want to do is in the end, where you want to verify that: Do updates to a child, via the parent, still work? ...
Linq for NHibernate Updates: Adding a new committer
Following several good patches, I have added Bobby Diaz to the Rhino Tools project, which currently includes the Linq for NHibernate implementation as well. I expect that the new stuff will be up in the repository shortly. Just to remind you, I am still looking for more volunteers to help with the implementation, so if you are into futuristic technologies, just dive right into the code and the implementation details. And be sure to send me (or Bobby) a patch or two.
NHibernate: Nullable DateTime Issues
System.DateTime is a value type in .Net, which means that it can never be null. But what happens when you have a nullable date time in the database, and you load it into a DateTime type? Consider this simple example. Mapping: <property name="UpdatedDate" nullable="True" column="updated_date" type="DateTime" /> Property: public DateTime UpdatedDate { ...
NHibernate Caching with SQL Cache Dependencies
NHibernate now has a cache implementation that supports SQL Dependencies from the Sql2005 and Sql2000.
The source is here: https://svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate.Caches.SysCache2
NHibernate code generation
Bobby Diaz has sent me the results of running the NHibernate Plugin for Visual Studio 2005 over the Northwind database, and I must say that they are good. Not perfect, but good. Another template that was recommended to me by Steve was MyGeneration "NHibernate lujan99 - .08" template, which I need to check.
Linq For NHibernate: Orderring and Paging
Bobby Diaz has implemented orderring and paging support for Linq to NHibernate, so this works: (from c in nwnd.Customers select c.CustomerID) .Skip(10).Take(10).ToList(); As well as this:var query = from c in nwnd.Customers where c.Country == "Belgium" orderby c.Country descending, c.City descending select c.City; Thanks again, Bobby, and the new code is on SVN.
Repositories 101
I got this question in an email today, and I think that it would make a good post. I broke it into two parts:We are moving from Delphi (RAD way) to real OO in C# + NHibernate. I've reading about DDD. Now I'm kind of lost about Repositories + NHibernate. I found code that uses a Repository<T> class, which I liked at first, but after a while I wondered... how can i test it ? or, tomorrow we can change from nhibernate to other thing... Let us talk about my Repository<T>, it is a...
Linq for NHibernate Updates
I got a couple of great patches yesterday and today, Bobby Diaz sent a patch to add support for Count() and DataContext like behavior. Jon Stelly went and cleaned up my code, turning it from a sleep-deprived hack into a respectable project. You can see his full list here. Thanks to their efforts, this now works:(from user in orm.Users select user).Count(); I changed the implementation of NHibernteLinqQuery to use the visitor pattern, which is the natural way that I think about walking through an AST. It is still very primitive one, but it does...
Googlize your entities: NHibernate & Lucene.NET Integration
I need to do full text searches on my entities, across many different fields, and with many different parameters. A while ago I heard about Hibernate Search(TM), and became envious. It took me about two days*, but it is (almost) here. Here is how I search my blog's posts at the moment:
using (ISession session = sessionFactory.OpenSession())
using (IFullTextSession ftSession = Search.CreateFullTextSession(session))
{
IList<Post> posts = ftSession.CreateFullTextQuery<Post>("Text:NHibernate and Title:Performance")
.List<Post>();
Assert.AreNotEqual(0, posts.Count);
}
And yes, I probably do have seamless integration with updating the indexes, so I wouldn't have to worry about it except...
Performance: Multiply Collections Fetch With NHibernate
We are back to the traditional model of Blog -> Posts -> Comments. Now, we want to load all the blogs, posts and comments and index them to improve search performance. A naive implemention will use this code: foreach (Blog blog in session.CreateQuery("from Blog").List<Blog>()) { ...
Implementing Linq for NHibernate: A How To Guide - Part 1
There is an appaling lack of documentation about how to implement Linq providers. The best resource that I could find is Fabrice's post about Linq To Amazon. The Linq In Action may provide additional information, but from what I have seen it is about using linq, not build a provider yourself. Since I would really like people to pitch in and help with the implementation of Linq for NHibernate (not that this is a hint or anything), I decided to document what I found out while building Linq for NHibernate. I strongly suggest that you...
On the sad state of NHibernate code generation
I wanted to generate NHibernate mapping & objects from the Northwind schema, to be able to run the same queries as the Linq samples. I evaluated several MyGeneration templates as well as a commerical product (GenWise). None of them had an output that I would dim acceptable. What od I mean by that? Singularizing the table names when creating an entity. Properties names that follow the .NET Naming Guidelines. ...
Linq for NHibernate
The code that I am going to show is working code. I have it passing tests on the March 2007 CTP, against NHibernate 1.2 CR1. Select entity and filter: var query = ( from user in session.Linq<User>() where user.Name == "ayende" select user ).ToList(); ...
What would happen to NHibernate after Linq ships?
I was asked this question, and I think that the answer is interesting enough to post here. There are two sets of technologies that MS is currently pushing. There is Linq, which is additional support for querying directly from the language, and there is the various ORM efforts that Microsoft is pushing. When the Linq bits will stabilize to the point where it is viable to start projects using them, there will be support for querying NHibernate with Linq. I have looked in detailed...
NHibernate In Action
Looks like Ben Scheirman have found the big secret. Just one question, what is this picture or? Aside from that, I can say that Hibernate in Action is a the best for anyone developing NHibernate. With the advent of NHibernate in Action, it is going to be even easier (no need to mentally translate from Java and EJBs anymore). I am looking forward to July 1th, when this book is coming out.
Watch me on DNR-TV
You can find the episode here, I am going to watch it now, more later...
NHibernate: Fetching multiply collections in one roundtrip
Please do not abuse, but this is really cool: IList list = (IList)s.CreateMutliQuery() .Add("select b from Blog b left join fetch b.Users where b.Id = :id") .Add("select b from Blog b left join fetch b.Posts where b.Id = :id") .SetInt32("id", 123) .List()[0]; Blog b = list[0] as Blog;
Note: Changes in NHibernate Connection Provider
Recently there has been some work on the connection model used by NHibernate. Specifically, this work was done to ensure that NHibernate will only hold an open connection for the shortest possible time needed. Some backgroud first: This change was driven by an attempt to port the Hibernate Swing demo app, and realizing that NHibernate and Hibernate 3.0 has different connection models. The Hibernate 3.0 connection model was driven by the need to release a connection on method boundaries, because some EJB containers are tracking resources, and would error...
NHibernate, Logical Deletes and the Second Level Cache, Oh My!
The comments says it all, I think:
public virtual void
Cancel()
{
/*
* NHibernate
trickery:
* Position
is mapped using where="IsCancelled = 0"
* When we
cancel a Position, we are logically deleting it.
* This plays
havoc with the 2nd level cache, because the
Employee.Positions
* is cached,
and the Position with the cached Id can no longer be loaded from the *
database.
*
Employee.Positions is mapped using cascade="all" and
inverse="true"
* So, we can
remove the Position from the Employee, which will make it
work
* with the
2nd level cache, but because it is mapped as inverse="true",
it
* will not
propogate the change to the...
NHibernate and large text fields gotchas
There are two gotchas associated with working with large text fields with NHibernate. The first is that you must specify type="StringClob" (or ColumnType = "StringClob" in Active Record), if you are using SQL Server, since NHibernate needs to set the Size property on the parameters. The second is that if you plan of letting NHibernate generate your schema, you need to specify sql-type="NTEXT" (or SqlType="NTEXT" in Active Record), otherwise NHibernate will generate an NVARCHAR field.
NHiberante Contest - with a secret (awesome) prize...
Pierre Henrie is running an NHibernate contest. I am not applicable for this contest, but I think that I can safely add that the prize is highly desirable for anyone using NHibernate. Go make a guess...
Localizing NHibernate: Contextual Parameters
I can't think of a good name for this post, but it is a very cool discovery. First, let us examine the scenario, a customer of mine has bought a database of localized data, which had the following structure: Now, what the customer wanted to be able to do is something like this: Product product = session.Get<Product>(5); productName.Text = product.Name; And get the correct name for the user's culture....
NHibernate Query Generator 1.8
Hi, there is a new version out, this one fixes the issues with the registry entries and can support 1.2 beta2 schema as well. You can get it here (no source yet, can't connect to the Subversion server for some reason).
NHibernate Web Cast Series: Thinking about the infrastructure
Here is a status report about the NHibernate Course that I talked about previously. I have talked with Justin, and at the moment is looks like we are going to do a web cast series about NHibernate. The draft syllabus can be found here, although this is merely a list of topics that we would like to cover. We are thinking of roughly 30 hours(!) or so of web casts, which should be enough to cover NHibernate from end to end, and maybe leave me out of a job :-). A you can imagine,...
OR/M and Performance
I spent most of the day going over an NHibernate application that was slow. The cause was most probably large number of queries for the database. I took my own advice and enabled performance logging for the application and let it run for a few days. When I read the logs today it looks like there were a number of pages where the number of queries was outside of any reasonable proportion. When I started reading the code for this pages, I realized that the problem wasn't with mis-use of NHibernate, or rather, it...
Complex Searching / Querying With NHibernate
Let us take the following form, the like of which has been known to cause grown man to cry. The client want something "very simple": I just want to be able to search on my policies, and this is the stuff that I think that I need now, and I'll need more in the future. Just a hint on the data model as relevant to this search form, it goes something like this: Polic: ...
NHibernate Mutli Query Support
Anything with Multi in it sounds exciting, except the mutli penalties mode. Developers are a suckers for performance. Give a developer the promise for a 0.5% performance gain, and they will jump through all number of hoops and go into any number of contractions just to be able to see the end of the rainbow. One of the questions that I was asked fairly frequently is "how do I get a paged view of the data, including the total count of the rows?" When I try to explain that this is not possible...
NHibernate Cascades: the different between all, all-delete-orphans and save-update
I have posted in the past about NHibernate's cascade being one of the places that require careful attention. But I run into an issue with it yesterday. The issue was that we had a typical parent-children scenario, but the requirement changed and we had to support orphans. That is, children without a parent. This isn't that big of a deal, after all, and I told Imperial to just change the cascade from all-delete-orphans to all, and forgot about it. I was called a few minutes afterward, and saw that the...
Messy database: NHibernate as the maid...
If you ever had to work with someone else's database (I assume that yours are perfect), you know that not all databases are nice and clean. In fact, some of them fail to do even simple things, like foreign keys. In some cases, FK is not even possible (think a view over a main frame table that you don't control). In such cases, almost invariablely, the database slightly corrupts itself. Sometimes it is a programmer error, sometime a failed set of commands without transactions, etc. The end result is that you get an...
Complex Queries With Active Record
There are some things that you simply can't do effectively with an abstraction. Take Hierarchical Queries as a good example. They are very hard in SQL, there is no good way to solve the issue in a portable way. Therefor, each database has its own method to handle this issue. In SQL 2000, you would build a table valued function that you would query, in Oracle, you use CONNECT BY, and in SQL 2005 and DB2 (that I know of) you can use Common Table Expressions. Out of the box, NHibernate can't handle this,...
The incomprehensible NHibenrate error contest
Did you get a hard to understand error from NHibernate and didn't know quite what to do? I am planning on going over NHibernate's error messages and see if I can improve the amount of information that they give you, but I would like to hear from you what the most annoying error messages are, and attempt to improve them (or at least explain why they are that way. Please note that I am only talking about errors that are hard to understand when you view the entire exception stack....
NHibernate Query Analyzer 1.1.9 - For NHibernate 1.0.3
Well, here is the first of the goodies. I have updated NQA to work against NHibernate 1.0.3, so anyone who upgraded can still use it. Please note that this is avialable for .Net 2.0 only. The binaries are here, but the sources are not in the usual place, instead they are in the NHibernate 1.0.x branch here. Have fun.
Wiki for NHibernate course
Head over here and check how I split up the stuff so far. This is on the wiki in purpose. I got a lot good feedback so far, and I would like to keep getting it. Feel free to edit the page and add / move topics in a more appropriate way.
Thinking out load: Any interest in an NHibernate Course?
Advance warning: I have not run this by anyone, and I have no idea if this is even possible. I mentioned that I am going to do an advanced NHibernate course in a couple of weeks. That is probably going to be a private one, for a client of us (well, a client of We! :-) ). Among my favoraite passtimes there is talking, and talking to a crowd is something that I had to deal with* and learned to enjoy. Seeing the response for my Active Record talk and the NHibernate's course that...
Advanced NHibernate Course
I am preparing a course for developers who already know NHibernate, but wants to get deeper. I would appriciate any comments. Topics: · Understanding how NHibernate Works: o Lazy loading – collections o Lazy loading – classes § Runtime inheritance § Proxy Validation o The reflection optimizer ...
Demo Code for Castle Forums Demo App
I figured that no one would find the link to the code if I just put it in the end (11 pages for a single post, wow!), so here it is. You can get the sources here. Have fun!
Building Applications Using Castle RC2: Part II
Last time I left we had a working data access layer, based on Active Record, as well as a scaffolding for editing users. We used TDD to drive the functionality of the application, and I intend to keep doing it this way while developing the functionality of the site itself. Before we start by building the initial list of tests, let us consider what we want to achieve... We want to have a forum system, so diplaying the forums, adding and browsing messages is very important, but managing users...
What should I use, NHiberante or Active Record?!
I was asked this several times lately, and it is time to try to make a more coherent statement about my thought in this matter. Active Record is a wrapper around NHibernate, which aims to make it easier to work with. The main benefit, in my opinon, is the time it takes to get a working entity from each. In NHibernate, you need to create the XML file (sorry Pierre, if I write attributes, they are the ActiveRecord ones :-) ), which can take more time than just slapping an...
Building Applications Using Castle RC2: Part I
Well, now that Castle RC2 is out, let us see what this release can do for us, shall we? After my recent talk, I got forums heavy on my mind, so let us build one. You can get the release here. I suggest that you would get the MSI installer. After installing the MSI, open Visual Studio and create a new project, you should see this screen: Choose Castle ActiveRecord Project and name the project "Castle.Forums.Model", name the solution (last text box) "Castle.Forums". Note:...
Code and Presentation from my lecture yesterday...
Can be found here. The code include all the dependencies that you need to build the project and start playing. Have fun...
Bringing it all together: Even More Magic,
So, I had done a couple of fairly cool stuff recently, but it is all in seperated pieces, let us try to bring them together and see what we get, shall we? ProjectionQuery<User> query = new ProjectionQuery<User>(Where.User.Name.Like("Ayende", MatchMode.Start), ...
Projections Support In Active Record
Ken, this post if for you... So, I have been a busy implementing crazy generics stuff and I can show you this: public class ProjectionQuery<ARType> : ProjectionQuery<ARType, object[]> Neat class, isn't it?Please not that this is not the same class that I shows here, that class has been renamed ScalarProjectionQuery, since it better fits its duy. What can you do with it? Well, things like this: ...
NHibernate Query Generator 1.7
Well, it is certainly an interesting release. This release contains very little code of mine, mainly minor adaptations of two wonderful patches that were sent to me. The first by Bas Jansen - which added inheritance detection from the mapping files. The second by Adam Tybor - which added support for projections and group by. Me, I just fixed a stupid bug by yours truly that would refuse to recognize exe...
Querying collections in NHibernate
I got some interesting replies to my post about what not to do with ORM. I got several comments back, and the major one was how to do a query about an entity collections with using string concantation, which I said was a code smell. Specifically, the most interesting challange was presented by Josh Robb, and it goes like this: Blog m:n Author 1:m Posts n:m Categories 1:m Comments Find all Posts where:...
How to get started with NHibernate?
A lot of my posts about NHibernate assume a certain level of familarity with the library and what it can do. For someone who doesn't know NHibernate, I believe that it so much nonesense... Anyway, this post is intended to give some information about kick-starting your NHibernate development. The classic articles about NHibernate, at least for me, are the Server Side .Net ones, here and here, by Justin Gehtland. There is, of course, the online manual, but that is for reference, not to get how to use it....
Object Relational Mapping: You are doing it wrong when...
You concatenate strings to build dynamic queries. You have no consistent way of querying the database. You need to create bad relational model to satisfy the object model that you want. You have a hard time mapping between the database and the objects, and you are not a beginner. ...
The cost of eager load...
This is the profiler results from trying to understand why I got very slow
responses from the server...
Notice what is costing so much time here. The first issue was that
the system was generated huge amounts of queries, and the quick & dirty
solution was to throw caching on top of this, which had a difference of three to
five orders of magnitude. The image above is after applying the caching, by the way, and there is no database activity in this call graph.
But performance continue to suffer, and I wasn't quite sure why. A quick look
at the profiler and...
NHibernate performance concerns
Darrel investigated NHibernate and came back with a Post Traumatic Stress Disorder. The issue he had was with NHibernate's Automatic Dirty Checking. The implementation fo this feature is done by keeping the state of the object when it was loaded from the database inside the session, and comparing the initial data to the current state of the object when flushing. The problem, in Darrel's words is: From my perspective there are two major drawbacks to this approach. First, considering the data you are manipulating...
NHibernate 1.2 Impressions
This is a completely non technical post, by the way. In the last two days I have been busy moving my current project to using NHibernate 1.2 and dropping all references to NHibernate.Generics in favor of NHibernate 1.2's native generics collection. (Finding some horrible business logic inside the Add/Remove delegates that was quite tricky to repreduce reliably). This project is "mostly read" system, and it feels significantly faster after doing the upgrade. I don't have any numbers, and it may be just a wishful thinking, but I see things responding...
And how much it would take to write NHibernate?
I'm not quite sure that I can believe the numbers, but here they are... 75 millions and over a thousand years... The line count seems particulary high, but I assume that this include the documentation as well. I run a check locally, and I get a number about half that much, for *.cs and *.xml files only.
NHibernate Generics: Deprecated On 1.2
I have updated NHibernate Generics to support NHibernate 1.2 . This update is very minimal and was done to ensure that you can move code to the NHibernate 1.2 without breaking stuff. Please consider NHibernate Generics library use as deprecated with NHibernate 1.2 and above. NHibernate Generics (NG from now on) always had two purposes. The first was to give generics capabilities to NHibernate, so I wouldn't have to do casts all over the place. The second was to automatically handle assoications between objects using anonymous delegates and a sprinkle...
Extending NHibernate Query Generator Code
So it has been out for 24 hours, and I got a couple of bug reports (fixed) and some interesting feedback. Ken is asking how you can extend the generated code and use SQL Functions from it. I had to fix a couple of issues which had to do with the amount of code I generated, right now I reduced the amount of code generated by 40% (with no affect of functionality, of course). After those changes (which also include making everything partial, we can start extending the Where class, this turned out to...
Unit testing with NHibernate / Active Record
One of the more difficult regions to test in an application is the data access layer. It is difficult to test for several reasons: It is usually complicated - fetching data effectively is not something trivial in many cases. It can be highly dependant on the platform you are using, and moving between platforms can be a PITA. It is usually hard to...
NHibernate Query Generator 1.5 Is Done! [Time With Magic]
I have been working (and blogging about it) for a while, and I think that I finally hit the right combination of keys to make it compile, so I am shipping it :-) If you fail to recall, it started as a simple way to generate criteria queries in strongly typed manner. The first version didn't do much, and was fairly simple. As soon as I started using it, I began to want more, much more. If I was working with an open compiler (Boo), I could have written this as an extentions and...
Interesting VB.Net Snippets
I using auto convertion to move code from C# to VB.Net, and I just run into this tidbit.Public Shared Widening Operator CType(ByVal expr As QueryBuilder(Of T)) As DetachedCriteria Widening? Apperantly there is also Narrowing operator. I'm not sure how they relate to the actual operation performed, though. But perhaps the best looking piece of code is this one: Post.FindOne( Where.Post.Blog Is Nothing ) Yes, this is real code. VB 2005 and NHibernate...
Complexity *= 10, Beauty *= 100
Trying to provide even more capabilities to the NHibernate Query Generator is turning tricky. The issue is that I would like to make stuff as natrual as possible. Due to this, I decided to take a break from my usual habit (sitting in from of the IDE and waiting for a nervous tick to cause characters to appear on the screen), and actually think about what I want to do. Then I went crazy with a mess of overloaded operators and generic query objects. The result, however, is this: ...
NHibernate Query Generator 1.2
NQG will now automatically create the NamedExpression and ManyToOneNamedExpression files, in a language of your choice, so you basically point it at a directory, let it run, and then just include all the files in that directory. You can get it here. Update: I fixed the warning in the generated files, and gave it a name without spaces, so it wouldn't break on download.
Suprise Feature Of The Month: Operator Overloading In Queries...
Like I said in my previous post, this is going to be all commentary. A series of compeltely unplanned actions on my part brought about an interesting result. Take a look at the following query: Comment commentFromDb = Comment.FindOne( Where.Comment.Content == "Active Record Rocks!" && Where.Comment.Post == post ...
Bringing Active Record and NHibernate Query Generator Together
This time, I am going to try to do it without commentry. The next post is where all the fun will begin. NHibernate Query Generator has been updated so it could work with Active Record as well. The way it works is simple, point it at an Active Record assembly, and it will spit out the generated query files. Usage: NHibernate.Query.Generator <cs or vb> asssembly.dll <output-dir> It supports generating C#...
Active Record Rocks!
I have been head down in NHibernate for the last several months, and as a result, I think that I started to miss just how enabling Active Record really is. This weekend I have been working on with it with a venegance, and I love it. The NHibernate 1.2 integration is really important, because it allows to infer even more stuff! Allow me to present, in all its glory, the amount of stuff needed to make a class persistent: The collapsed properties merely hide the get/set...
Working with deep object graphs and NHibernate
Note, this image was generate using Active Writer and represnt a domain model similar to a project I am currently working on. I spared you the prolifieration of DateTime in the model and merely put it in three or four places just to show what it was in general. (continued below) Now, this model is not showing unrelevant additonal entities (and entities attributes) but it is complete enough that you would understand the general theme of things. The requirement is finding all potential employees in the...
Should you use NHibernate with Stored Procedure?
In my previous post about NHibernate and Stored Procedures, I showed how it can be done, and I closed of with this:The disadvantages - You take away from NHibernate the ability to comprehend the structure of the tables, this mean that it can't do joins, eager fetching, etc. This is extremely important capability that just vanished. Likewise for queries, NHibernate's abilities to query your objects is being severly limited using this method of operation. Galen commented: It sounds like the following two...
The little query that could... drive me crazy
I have a piece of code that has to calculate some pretty hefty stuff over a large amount of data. Unfortantely, that large amount of data took large amount of time to load. By large amount I mean, I walked away and had time for a coffee, chit chat, about three phone calls and a relaxing bout of head banging, and it still continued to pry into the database, and likely would continue to do so until the end of time or there about. This calculation has two main charactaristics: ...
For the adventerous sort: Active Record + NHibernate 1.2
I branched Active Record to move it to NHibernate 1.2, because of some needed features from NHibernate 1.2 that simply do not exist in NHibernate 1.0.2. The branch at the moment should handle generics natively and easily, so you should be able to do this: [ HasMany] public ISet<Post> Posts { ... } And Active Record would figure out all the rest. (Although it is probably recommended to give it at least...
Using SQL Functions in NHibernate
Often, when introducing NHibernate, I need to integrate with existing database and infrastructures. Leaving aside the question of stored procedures (since I already expanded on that in length here), which are avialable on NHibernate 1.2, I want to focus on using SQL Functions here. (One again, I'm back to the Blog -> Posts -> Comments model) Now, there are four types of SQL Functions that you might want to use: Scalar functions that are a part of an entity....
Using NHibernate.Generics with NHibernate 1.2
If you are using NHibernate.Generics with NHibernate 1.2, you may run into casting issues, this is because NHibernate.Generics and NHibernate 1.2 both tries to make the collections generic. You can either stop using NHibernate.Generics (their main purpose, allowing generic collections in NHibernate) is no longer needed. But their secondary purpose, automatic syncronization between related properties is very nice in many scenarios. Until I'll get around to porting them to 1.2, you need to specify generic="false" in the mapping of all collections that uses NHibernate.Generics for them to work.
NHibernate Mapping File Item Template
I find myself creating it quite a bit, and I got tried of copy/paste to add the item, so I create an item template for VS 2005. You can download it here. I am thinking about creating a project template as well (I keep creating small projects to test stuff, or abusing my existing NHibernate.Generics project), but I hate the GAC and I don't want hard coded paths in the template. Any ideas how I can add the DLLs themselves to the template?
OR/M and SQL Injections
ScottGu is talking about SQL Injections and he mentions that neither stored procedures nor OR/M are a complete protection from it. In a way, he is correct. If the stored procedure that you are using is called sp_executesql, then you are not protected from SQL injection. A more problematic approach is when your SP uses sp_executesql to do some of its work (usually because it need to work on a table dynamically, or your precedecor was a sadistic freak that enjoy doing things the really hard way). Users of ORM are...
PluralizingNamingStrategy for NHibenrate
One of the nicest parts of developing with NHibernate is that you can get NHibernate to generate the table from the mapping. This is extremely useful during development, when changes to the domain model and the data model are fairly common. This is even more important when you want to try something on a different database. (For instnace, you may want to use a SQLite database during testing / development, and SQL Server for production, etc). I intend to post soon about unit testing applications that uses NHibernate, and this functionality is a extremely important in...
NHibernate Caching: The Secong Level Cache Space Is Shared!
Let us assume that you have an architecture that demands that you'll have a database per client (quite common, by my experiance), but the application layers are the same. This is usually done for reasons of security and/or scalability. So there is no way a client can get information for another client. This is fairly simple to handle with NHibernate, you just create a session factory per each client. This is actually an advantage, since you can start playing with the implementations of the classes for each client. (Yes, you are reading me correctly....
NHibernate 1.2 Beta1 Released!
Yesterday the beta for NHibernate 1.2 was released, the new features that interests me are: Native generics (you no longer have to use the NHibernate.Generics compatability library). Batching support (SQL Server only) - huge perforamance increase in some scenarios. Support for using Stored Procedures. Support for named connection strings. ...
Using NHibernate With Stored Procedures
No, really for real this time. I opened my mailbox today to find a very interesting message from the NHibernate commit logs: NH-258 - Custom SQL support (including stored procedures) It may look fairly innocent comment, but it has quite an impact on several nay-sayers that will clutch stored procedures until you pry them out of their cold dead hands. Also, sometimes Stored Procedures (or raw SQL) are useful :-). So, armed with nothing but...
Thinking about APIs: Advance Usages
You may have noticed that I have create some wrappers around NHibernate, to make it easier to work with. NHibernate's API is very rich, and it can get pretty long if you are not careful. Consider the following: Session.CreateCriteria(typeof(Post)) .Add(Expression.Gt("PostedAt", DateTime.Now.AddDays(-3))) ...
Batching support in NHibernate
As of about 90 minutes ago, NHibernate has batching support. :-D All the tests are green, but there may be things that broke in exciting ways, so I encourage you to try it out and see if you can break it. This functionality exists only for SQL Server, and only on .Net 2.0 (for complaints, go directly to the ADO.Net team). You can enable this functionality by adding this to your hibernate configuration. < add...
Measuring NHibernate's Queries Per Page
One of the biggest problems with abstractions is that they may allow you to do stupid things without them being obvious. In OR/M-land, that usually means SELECT N+1 issues.The problem is that you often develop a certain functionality first, and only then realize that while you tested, all was fine and dandy on the five items that you had, but on the real system, you have 5,000, and the DBA is on its way to ER...Anyway, I am currently working with Web Applications, and I wanted to get a good indication about what pages are troublesome.Being who I am, I...
The use of caches in OR/M
I recently talked quite a bit about caches in NHibernate, and I am a great believer in careful use of it in order to give an application much better performance. Frans Buoma, however, does not agree. Just to note, Frans is the author of LLBLGen Pro. First, let me point to an issue that I have with the terminology that he uses. When Frans is talking about cache and uniquing, he refers to a term generally (at least by N/Hibernate & Fowler) called Identity Map. Frans: A cache is an object...
Handling nullable datetime in NHibernate : The Interceptor
System.DateTime is a value type, and as such, cannot be null. The default value for DateTime in .Net is DateTime.MinValue, which equals to 01/01/001 00:00. The problem is that SQL Server's dates start at 1753, or there about. This is usualy solved in .Net 2.0 using Nullable<DateTime> (or DateTime? in C#), but my "entities" are messages to web services, and are generated from WSDL, so they lacked this nice feature. I also didn't realize that some of the DateTime values were nullable until pretty late into the game. After a...
The Secret Life of NHibernate's Caches
The fastest way to get data from the database is not getting it from the database. I talked about NHibernate's caches in the past, but I was mostly focused on entities and collection caching. Those are fairly easy to grasp. You load an entity once, and the second time, it doesn't get loaded. Collections are slightly more complicated, since they require you to know what is going on (otherwise, you may get into a bit of problem, like I did), but they really reduce the amount of work the database...
NHibernate Generics 1.0.10
NHibernate Generics 1.0.10 is a small bugfix release that is intended to allow inheriting from EntityList<T>, EntitySet<T>, etc. Check here for the scenario that was fixed. As usual, binaries and code are here
And sometimes I don't want to use generics
Take a look at this: IList list = UnitOfWork.CurrentNHibernateSession .CreateCriteria(state.RecordType).List(); RecordType is a System.Type that is loaded from the database as one of the properties of the state. This means that I literally switch stuff around just by adding...
NHibernate Mapping: Creating Sanity Checks
Here is a very easy way to find out if your database schema is still the same one that NHibernate expects: [Test] public void AllNHibernateMappingAreOkay() { ...
Working with high levels tools: A Performance Perspective
The performance question was raised in the Castle's Forums, hammett has posted a blog entry about it, but I have my own two cents to add. The question was about a performance test made with NHibernate vs. ADO.Net, resulting in NHibernate being quite a bit slower. Just to note, at the moment I'm talking about performance in terms of milli seconds, I'll talk about performance in terms of days in a bit. A test between ADO.Net and NHibernate is going to be meaningless for the most part. Sure, you can issue a SELECT to get...
NHibernate Criteria API: Operator Overloading
Today I took the time to add a small but extremely nice feature to NHibernate, operator overloading with the criteria API. I used Steve Eichert's solution (thanks, Steve!). For reference, here is the the code that I added (below are some examples of using it): #region Operator Overloading ...
New Version of NHibernate Query Generator
After using it for a couple of days, I made the following improvements: Added Eq() and IdIs() to many-to-one references, so now I can issue this statement: ICollection<Order> orders = Repository<Order>.FindAll( Where.Order.Customer.IdIs(15) ); It seems like we are using this quite a bit in our applications, mainly from query strings. Added support for VB.Net ...
NHibernate and the second level cache bug: conclustions
Well, I posted that the bug was fixed in the SVN repository, but it was merely moved to another location, not fixed. Futher investigating showed that the same issue appear in Hibernate. Further investigation showed that this is by design. (Indeed, when trying to fix the "bug", I have run into the same conclustions, and was about to suggest the same "by-design" fix.) The issue is, to remind you, deleting an object that reside in a collection on the second level cache. The Hibernate FAQ entry about the issue...
NHibernate Query Generator Source Avialable
You can get it here, patches are welcome :-)
Introducing the NHibernate Query Generator
Okay, it looks like I can track down fairly easily what books I read, when I read Working Effectively with Legacy Code, I wrote Rhino Mocks. Now I am reading Applying Domain-Driven Design and Patterns, and I wrote the NHibernate Query Generator. So, what is this all about? NHibernate has two major API for querying objects. The first one is called the query API, and uses HQL, a language similar to SQL but with OOP aspirations. The second is called the criteria API, and it is far simpler API, but...
Debugging NHibernate: A Waste Of Time :-D
Sigh. It looks like I won't be able to fix the bug that I thought to fix. Someone fix it already. I have grown attached to this bug, in the short time that I knew it, but I guess that it is the way of life, bugs come and go. If anyone is interested, it has to do with deleting an item from a collection that is cached on the second level cache, and then accessing the previous owner of this item from another session. Repreducable in 1.0.2, fixed in 1.2.0 alpha.
Deep Diving Into NHibernate: The Tests Structure
Just a quick note before continuing. In NHibernate, most tests inherits from the abstract NHibernate.Test.TestCase class. This class is responsible for the infrastructure of the test. By that I mean that it instansiate a Session Factory, create the appropriate tables, etc. A test fixture specify how to find its mapping using these two properties: /// <summary> ...
Deep Diving Into NHibernate: The Second Level Cache
I mentioned before that I am now part of the NHibernate project, but so far I haven't done much with it. In what turns out to be a nice timing, I found a fairly obscure bug that I hope that I can fix, and I am going to bore you with all the nitty gritty details of how I am going to do it. Before I can begin, let me describe what area I am going to work at. NHibernate has two level of caches. The first level is the...
NHibernate Best Practice: Avoid using CHAR/NCHAR columns as discriminators
One of the things that I do is provide NHibernate support for some of our clients. This gives me the chance to see NHibernate used in many different scenarios. A few days ago I got a call, they couldn't get discriminator values to work with NHibernate. That was very surprising, since I worked with them before, and they are well tested code. After looking at the code and the mapping, I was still at a loss. Everything looked fine, I couldn't figure out what was happening. I still got "WrongClassException: Object with id: 1...
Using Active Record As A Rule Engine
I posted a riddle about how to use Active Record as a Rule Engine, here is the answer. First, just to remind you of the scenario: A rule engine that can process big amount of data. The engine will run as a Windows service, and not as a part of another application. Throughput is important, as well as flexibility in the rules and what they can do. The processing of each rule can be quite complex, so it is important that the rule engine will not limit what the rule can do. The...
Riddle: Active Record as a Rule Engine
I mentioned in a previous post that I used Active Record as a Rule Engine, and a couple of people asked just how. Before I will post the answer, I want to see if you can come up with the same idea. The scenario: A rule engine that can process big amount of data. The engine will run as a Windows service, and not as a part of another application.Throughput is important, as well as flexibility in the rules and what they can do. The processing of each rule can be quite complex,...
NHibernate's "Stored Procedures" - Named Queries
First things first, don't get too excited, NHibernate doesn't support Stored Procedures (yet). What I am talking about is encapsulating HQL queries in a similar manner to the way stored procedures work. A little background before I start talking about the technical details. When using NHibernate, I'm usually pushing the use of NHibernate's Criteria approach, since this is by far the most easy way for people to comprehend how to query the database using NHibernate. While for simple uses HQL is very simple: ...
NHibernate Commiter
I just wanted to announce that I have been choosen as a commiter in NHibernate :-D
NHibernate’s association is cool
I need to preface the cool part with also mentioning that <any> is a part of an evil plot to overtake the world, so don’t use it if you don’t know what you are doing. If you do, however, it is one hell of a feature to have.
Currently I’m using it for a set of rules, which can be applied to several objects, which does not have a common ancestor. This is usually a problem, since I have no way to map those objects to the database and back.
It turned out that NHibernate has support for <any>...
Advanced Uses For OR/M
There
is another holy war converging about the SP vs. Parameterized SQL topic.
I got into one not long ago, and I wouldn't get into this one if there wasn't
some new stuff brewing in it.
Eric
Wise started this with a The
Pragmatic Adhoc SQL vs Stored Procedures Discussion, Jeremy D. Miller responded
with Why
I do not use Stored Procedures and then Eric posted a new post, this time
with In
Response To No Stored Procedures which has some new questions that I have
not seen before.
1.
About the security, naturally, security
is a multi layered approach. In the database, I would grant permissions to
views or tables according to the...
NHibernate Best Practice - Assert Cascade Behaviors
I've said it before, one of the trickiest parts on NHibernate is the cascade behaviors. Why is it tricky? Because a slight configuration can cause the application to get exception at best, or silently lose data at worst. How does this work? Let us assume that I have the Blog -> Posts model, and I want to create a new post. I can do this like this: using(ISession session = factory.OpenSession()) ...
NHibernate.Generics 1.0.7
I'm pretty ashamed to admit it, but I managed to foul up IEnumerator<T> for EntityDictionary<T,K>. I was very surprised to realize this, I assure you, I thought that at this point I could be trusted to handle a simple collection delegation, but apperantely this is not the case. There is a new version which fix this issue, add some better error messages, etc. As usual, you can get it here.
Pissed Off By Vanatec OpenAccess
I was mentoring NHibernate today, and I run into this advertisement when doing a search on Google about NHibernate: Stop Hibernating. Start real O/R Mapping. - using Visual Studio. Read why! I clicked on the link, intrigued that I wasted so much time using a fantasy OR/M. I'm a sucker for Real Programmer Tools & Practices, so I couldn't help myself. I will not get into whatever it is moral to buy adwords on someone's else products, there is...
25 Reasons Not To Write Your Own Object Relational Mapper
Not long ago I was ask to evaluate what features are need to build a robust data access layer. The choices were:
Build / Code Gen a DAL
Use an existing Object Relational Mapper
Build an Object Relational Mapper spesific for this application.
DataSets were not appropriate to this application, so the the first and last choice were essentially the same. The database schema...
DLinq Answers
I posted this two days ago, and I got some answers to share. I'm not an expert on DLinq, so this isn't writ in stone. DLinq supports lazy loading, but call it delay / deferred loading. Not sure why they pick a different term than the standard one in other O/RM. It also supports rich eager fetching support, which is...
Active Record Internals
Hammett is publishing a set of article about how Active Record is working internally. They are very detailed, without boring you with thousands of lines of code.Article #1 - Introcuding Active RecordArticle #2 - Active Record Initialization.
Replacing O/RM Is Hard
No, I'm not abandoning NHibernate to greener pastors, I'm talking about this post.I'm not sure what the point of the author was, but on first reading, it read like FUD to me. Maybe it is the general tone of the post, or that there are a lot of numbers without any clue how the author got them, but that was my first feeling. A lot of the points that are raised are valid, but I just don't understand where the numbers came from.I had a math teacher that used to look at a student excersize and say: "And suddenly there...
NHibernate & .Net 2.0 Nullable Types
If you want to use NHibernate with .Net 2.0 Nullable Types (int?, DateTime?, etc), all you need to do is to specify full type name of the (non nullable) property.So, if you've something like "DateTime? DueDate { get; set; }", the mapping will looks something like this: "<propery name='DueDate' type='System.DateTime'/>"You don't need to do anything else.
Concurrency Questions
I was asked a question today, and I'm not sure what the answer is. The issue is with optimistic concurrency on the web. I got an edit page that allows a user to edit a page. I want to throw a concurrency exception if a second user has changed the object while the first user was editing it. The issue is that when I get the values of the form back when the user is finished editing, I no longer know what version of the object the user has edited. It looks like...
Schema Generation
I just did a little test with NHibernate's Schema Generation capabilities, and I'm very impressed. The schema is very much like I thought it would be, and it makes sense. So far I've been avoiding it, thinking that I can do much better and that it is something that I have to do by hand. This caused quite a bit of pain when I needed to make a change in the object model that required a DB change. I'm thinking that I'll be able to just use it to easily and painlessly re-create...
Bulk Data Operations Using NHibernate
If there is one thing that NHibernate (and most other O/RMs) are not very good at, it is bulk data operations. What does it mean? Well, let's take a simple case of wanting to delete all the records in a table. (I'm going to use Active Record Blog Sample for the sample, it is much simpler). Let take this, for instance:Post.DeleteAll(); This will delete all the rows from the Posts table. Really easy to write or do, but what is the meaning here? What goes under the cover is something like: ...
Advnace Mocking Scenarios With Active Record (using Rhino Mocks)
My recent post sparked some discussion in the Castle Mailing List, with some question of how to handle more complex scenarios. I managed to code those without much problem, as you can see below, but a few words first. This method essentially mocks NHibernate for Active Record. This means that you have to understand what is happening (which is not a bad idea). I'm intimately familiar with both Active Record and NHibernate, and I had to look at the source to see what was happening. If you intend to use this method, I highly...
Testing ActiveRecord objects
Steve has posted a question about how to test ActiveRecord objects, since they have static methods with no easily visible places to shove a mock implementation. One of the core ideas of ActiveRecord is that of a Scope. Fairly often you are not aware that you are using it, since it is entirely possible to use it impliciltly. But when you are using SessionScope to allow lazy loading, or TransactionScope to ensure referential integrity, you are using the scope. In its simplest form, a Scope simply holds a session, the default...
Learning about LLBLGen
I’ve been reading the LLBLGen documentation for the last couple of days, and it’s an interesting read. I think that I should say first that I have a very strong bias toward NHibernate, so please don’t think that I’m an impartial observer here. Before I really dove into NHibernate, I read Hibernate in Action (still the best book for learning Hibernate, in my opinion). I’m trying to give LLBLGen (who came up with this name? It is worse than Microsoft’s naming) the same treatment, and read the entire manual before I...
RedHat acquires JBoss
This is much better than Oracle, in my opinion. Still, it means that NHibernate (and Hibernate) are now under the Red Hat's umbrella. I wonder if it will make it an easier or harder sell when I try to convince people that "Yes, Open Source Software doesn't mean that you are all along with hungy wolves all around you."
Underused NHibernate Feature: Creating Objects In The Select Clause
I got a comment today from Jim Bolla asking about this query: select new Address(c.Address, c.City, C.Zip) from Customer c His comment was: I've been using NHibernate for at least 6 months now and haven't heard of this feature. Does this really work? What are the requirements/limitations? Is this in the documentation? Or even in the example code/tests? As he didn't leave an email or another...
NHibernate Query Analyzer 1.1.3 Release
Don't ask about the version number, it just is. I haven't done an all-nighter in quite a while, and while it was fun to do, I'm not thinking very clearly right now. Here is the details about this release: I finally got around to take a good hard look into NHibernate Query Analyzer (AKA: NQA). I haven't update it in a while, and that is a shame. There was an issue with query translations when using parameters that kept me from going forward for a long time. Today I bit the bullet and...
Reflection & Locale
Seems like I made a mistake in the previous post. The problem with the Turkish I wasn't supposed to be solved on the Reflection API level, but earlier than that. The issue seem to be the string transformation done on a property name (for instance, if I want NHibernate to use the field and not the name) rahter than what I pass to GetField() and deriatives) where NHibernate didn't took into account that lowering the case of a character may result in a different letter on other locales. The issue was already fixed on NHibernate CVS,...
NHibernate Generics & EntityList - Update
Okay, the code is in the Subversion repository, but I'm not ready to release it yet. I've a shameful confession to make first: I never used an IList with NHibernate (or ActiveRecord) before, so I'm not really sure whatever my code makes good sense or not. And, in addition to that, I haven't had the time to test it propertly. I would appriciate it if someone who had used it before could take it for a spin and tell me what they think the bad points are.
Verifying you Data Access Layer when using NHibernate, Active Record, And Friends
I sometimes run into situations where people think that ORM is a magic word for no-work-required. This is especially true when they tend to realize that a few hours (on a small project, or a few hours here and there on a larger one) in front of an XML editor and some really simple classes, can more or less eliminate the need of a DAL. It's tempting, I can write a functional DAL very quickly, but I also need to make sure that I test it. The problem is that you may be tempted...
NHibernate 1.0
Yes! NHibernate reach a 1.0 status! I've been using it for a long time, and it always been a pleasure. Thanks to the NHibernate team!
Obscure N/Hibernate Feature: &
NHibernate & Hibernate has a really cool feature by which you can map two columns in a database to any arbitary object. The first column is the type of the the object you want to create, and the second is the id of the object you want to create. Unsurprisingly, this feature is called <any> / <many-to-any>. It's recommended that you wouldn't use it since it's not very OO, but sometimes there isn't much choice. I run into such a situation recently. I've a set of rules that can be applied to...
Using NHibernate Query Analyzer
The reason that I created NQA is that I wanted to understand how NHibernate did its magic. I was rathered surprised when people started using it to work with NHibernate on a regular basis. I added some schema editing features that people asked for them. I then turned to greener pastures, ActiveRecord, namely. I recently got into situations where it can't go. (Really weird schemas, etc). After I stopped feeling betrayed (What do you mean, you only read 99% of my mind?) I sat down to code it. That was where NQA was really...
Bug fix in NHibernate.Generics
I fixed a small bug in NHibernate.Generics, regarding safe double calls of the EntitySet<T>.Remove() method. George, thanks for finding it. I don't think that a normal usage would find the bug (a case of using a belt and a suspenders), but most edge cases would be hit by hit. The update version is available here.
NHibernate on .Net 2.0: Part IV - The Sucess
You can find all the juicey details here, but the short of it is that I've tested it and it worked. I have a working implementation which I could use to get smart generic collections for my business objects. It's very cool, and it's amazing that ~400 lines of code took so much research. Oh well, I worked today to be lazy tomorrow :-)
NHibernate on .Net 2.0: Part III
I managed to build an addon to NHibernate that would allows you to use generic collections in NHibernate. Well, one collection,
EntitySet<T>, but it's the principal that matter, and it's very
easy to write additional classes to do the same for the other
collections if you really wants it. I used a custom
PropertyAccessor, and I'm planning on releasing it tomorrow (once I
wrote enough tests). But here is the client code that you'll have to
write: Post post = new Post(); blog.Posts.Add(post); ...
NHibernate on .Net 2.0: Part II
My first attempt in using generic collections in NHibernate was to
just make NHibernate grok my custom collection. I took a look in the
code, and it seemed rather straightforward to do so. I posted to the developer list and got the following response from Sergey, the lead developer: Have your collection class implement an interface (class MyCollection: IMyCollection)
Create NHibernate-specific wrapper class (PersistentMyCollection :
PersistentCollection, IMyCollection) which functions as a...
NHibernate on .Net 2.0: Part I
I've been developing in .Net 2.0 [without ReSharper* :-( ], and I'm using NHiberante and Active Record for
the data access layer. There were no problems with regard to their
usage, but there are things that I don't like in the interface
that they gives you. The problem is that you get an untyped collection.
This was sort of OK in 1.0/1.1 but it's a really eye sore for
developing in 2.0, where I want everything to be a generic type-safe collection.
Another issue with NHibernate is that the syncing between relationships
is not automatic. That is to say, the following code is essentially a
no-op:Blog blog = session.Load(typeof(Blog),1); ...