Ayende @ Rahien

Refunds available at head office

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!

image

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 just stared at the profiler in shock, not believing the breadth of information that it gave me. More specifically, error detection can be a true godsend in many cases. But just being able to flip between the code and what is going on is invaluable to explain what is going on. And today I had the chance to use it as a detective tool, trying to figure out what exactly is causing a page to issue hundreds of requests. The Stack Trace feature was invaluable in tracking down exactly what is going on.

Just for that alone, it was worth all the time, effort and money that I put into it.

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:

image

This allow us to update the version of the aggregate even if it wasn’t actually changed.

Of course, if you wanted a physical lock, you can do that as well:

session.Lock(person, LockMode.Upgrade);

Which would result in:

image

Pretty easy, even if I say so myself.

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 of that. This don’t see the problem, or feel it. And while they could fix it if they caught it in time, trying to come back to an existing application and fix all the many places where they assumed database access is free is a daunting task.

Therefore, I have set out to solve the problem. Obviously it is a problem with the developers not paying attention, but how can we deal with that?

Well, you could buy the NHibernate Profiler, which is my official recommendation. Or, if you don’t feel like spending money on this, you can utilize the following interceptor. That will make the developers sit up and notice when they start talking to the database.

public class SlowDownDudeInterceptor : EmptyInterceptor
{
    public override SqlString OnPrepareStatement(SqlString sql)
    {
        return sql.Insert(0, "waitfor delay '0:0:0.5'" + Environment.NewLine);
    }
}

Don’t go to production with this!

Why Defer Loading in Entity Framework isn’t going to work

When I finished reading this post I let out a heavy sigh. It is not going to work. Basically, the EF is going the same way that NHibernate was in NHibernate 1.0 (circa 2005!).

Let me show you how. in the post, the example given is:

public class Category
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    public virtual List<Product> Products { get; set; }
    ...
}

This looks like it would work, right? The way the EF is doing this is by creating a proxy of your class (similar to the way that NHibernate is doing that) and intercepting the call to get_Products.

It has a few problems, however. Let us start from the most obvious one, program to interface not to implementation. Exposing List<T> means that you have no control whatsoever about what is going on with the collection. It also means that they have to intercept the access to the property, not using the collection. That is bad, it means that they are going to have to do eager loading in all too many cases where NHibernate can just ignore it.

Let us more on a bit, and talk about the inability to support any interesting scenario. If we look at collections with NHibernate, we can take this:

Console.WriteLine(category.Products.Count);

To this SQL:

select count(*) from Products
where CategoryId = 1

With the approach that the EF uses, they will have to load the entire collection.

But all of those are just optimizations, not the make-or-break for the feature. Here is a common scenario that is going to break it:

public class Category
{
    private List<Product> _products;
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    public virtual List<Product> Products { get { return _products; } set { _products = value; } }

    public void AddProduct(Product p)
    {
        // do something interesting here
        _products.Add(p);
    }
    ...
}

There is a reason why the default proxies for NHibernate force all members of the entities to be virtual. It is not just because we think everything should be virtual (it should, but that is not a discussion for now). It is all about being able to allow the user to use a real POCO.

In the scenario outlined above, what do you think is going to happen?

AddProduct is a non virtual method call, so it cannot be intercepted. Accessing the _products field also cannot be intercepted.

The end result is a NullReferenceException that will seem to appear randomly, based on whatever something else touched the Property or not. And however nice auto properties are, there are plenty of reason to use fields. Using auto properties just mask the problem, but it is still there.

Oh, and if we want to use our POCO class with EF, forget about the new operator, you have to use:

Category category = context.CreateObject<Category>();

Hm, this just breaks just about anything that relies on creating new classes. Want to use your entity as parameter for ASP.Net MVC action, to be automatically bounded? Forget about it. You have to create your instances where you have access to the context, and that is a database specific thing, not something that you want to have all over the place.

And I really liked this as well:

The standard POCO entities we have talked about until now rely on snapshot based change tracking – i.e. the Entity Framework will maintain snapshots of before values and relationships of the entities so that they can be compared with current values later during Save. However, this comparison is relatively expensive when compared to the way change tracking works with EntityObject based entities.

Hm, this is how NHibernate and Hibernate have always worked. Somehow, I don’t see this showing up as a problem very often.

Final thought, why is the EF calling it Defer Loading? Everyone else call it lazy loading.

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:

image

With the following schema:

image

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' where o.Name = 'b'")
    .ExecuteUpdate();

Executing this code will make NHibernate execute the following SQL statements:

image

image

image

image

image

image

As you can see, we have executed a very simple query against the model, which translate to a fairly complex data model (needing to update three separate tables. We can also see that we are doing significant effort to maintain the illusion of a single query (that is why we need the temp table here).

But we are not limited to just updates, we can also do deletes:

s.CreateQuery("delete Owner o where o.Name = 'b'")
    .ExecuteUpdate();

Which result in:

image

image

image

image

image

image

I think that by now you are already familiar with the pattern :-)

As for insert statements, they are supported as well, but there are some limitations. In particular, you have to use an identifiers generation strategy that can generate identifiers in the database (sequence or identity), and there are some limitation on how you can make this work in several complex hierarchies. Using a simple Table Per Class, the following HQL works:

s.CreateQuery("insert into Individual (Name, Email) select i.Name, i.Email from Individual i")
    .ExecuteUpdate();

And generates:

image

All in all, this is a really awesome feature.

Thanks, Fabio.

A good refactoring session is…

One in which I get to remove a lot of code. Here is a particularly interesting tidbits, SqlStatement is one of the core classes in NH Prof, look what I did to it:

image

For those of you not used to reading diffs, the orange marking on the side bars are removed lines. It dropped from a 484 lines to 153.

Challenge: Find the bug

This piece of code caused a crashing bug on a QA server ( and we are lucky it didn’t go to production ).

image

Can you spot the bug?

I will give you a hint, it is the code that isn’t there.

Published at

Originally posted at

Comments (38)

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>();

NH Prof: Why you should use it

This is a screen shot one of NH Prof’s users has sent me:

image

A picture is worth a thousand words, I believe is the saying. But in this case, I think it is worth about 1755 queries.

Tags:

Published at

Originally posted at

Comments (8)

A case of massive stupidity

This is a story about a bug that frustrated, annoyed, and nearly drove me mad. It also cost me ridiculous amount of time. The problem? The communication from the profiled application to the profiler with NH Prof is done using a Protocol Buffers network stream. The problem? It kept failing. Now, networks are unreliable, but they are not that unreliable, especially since all my tests are focused on local machines scenario.

I tried quite hard to create a very reliable system, but I was growing extremely frustrated, it failed, sometimes, in a very unpredictable manner, and in ways that looked like the entire idea is broken. To add insult to injury, any isolated test that I run worked perfectly. Out of ideas and nearly out of of my mind, I turned to the old adage: “If it doesn’t work, kick it, if it still doesn’t work, kicker it harder” and created a stress test that basically run several of the problematic tests in a loop until I could finally reproduce it in a more or less consistent fashion.

It was fairly clear that I am getting a lot of errors when reading the data, and for a while, I focused on that, thinking that I wasn’t handling the connection properly. But even after I did a lot of work on hardening the connection code, it still failed quite often. Now it didn’t fail on reads, it failed on missing data that the tests expected to be there.

After a while I started concentrating on the writing side, I changed the code to write the data to a file, rather than a network stream. At that point, I was pretty sure that my file system was working properly, and I intended to do analyses of the file as I load it. Imagine my surprise when I found out that the file, too, was corrupt. That made me abandon the reading-cause-the-error scenario, and cause a total focus on the writing part. After a while, I managed to get a clue, in the form of the following error:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Google.ProtocolBuffers.CodedOutputStream.WriteRawByte(Byte value) in C:\OSS\Buffy\ProtocolBuffers\CodedOutputStream.cs:line 530
   at Google.ProtocolBuffers.CodedOutputStream.WriteRawByte(UInt32 value) in C:\OSS\Buffy\ProtocolBuffers\CodedOutputStream.cs:line 534
   at Google.ProtocolBuffers.CodedOutputStream.SlowWriteRawVarint32(UInt32 value) in C:\OSS\Buffy\ProtocolBuffers\CodedOutputStream.cs:line 464
   at Google.ProtocolBuffers.CodedOutputStream.WriteRawVarint32(UInt32 value) in C:\OSS\Buffy\ProtocolBuffers\CodedOutputStream.cs:line 480
   at Google.ProtocolBuffers.CodedOutputStream.WriteTag(Int32 fieldNumber, WireType type) in C:\OSS\Buffy\ProtocolBuffers\CodedOutputStream.cs:line 458
   at Google.ProtocolBuffers.CodedOutputStream.WriteMessage(Int32 fieldNumber, IMessage value) in C:\OSS\Buffy\ProtocolBuffers\CodedOutputStream.cs:line 220
   at HibernatingRhinos.NHibernate.Profiler.Appender.Messages.LoggingEventMessage.Types.StackTraceInfo.WriteTo(CodedOutputStream output) in C:\NHProf\HibernatingRhinos.NHibernate.Profiler.Messages.cs:line 560
   at Google.ProtocolBuffers.CodedOutputStream.WriteMessage(Int32 fieldNumber, IMessage value) in C:\OSS\Buffy\ProtocolBuffers\CodedOutputStream.cs:line 222
   at HibernatingRhinos.NHibernate.Profiler.Appender.Messages.LoggingEventMessage.WriteTo(CodedOutputStream output) in C:\NHProf\HibernatingRhinos.NHibernate.Profiler.Messages.cs:line 843
   at Google.ProtocolBuffers.CodedOutputStream.WriteMessage(Int32 fieldNumber, IMessage value) in C:\OSS\Buffy\ProtocolBuffers\CodedOutputStream.cs:line 222
   at HibernatingRhinos.NHibernate.Profiler.Appender.Messages.MessageWrapper.WriteTo(CodedOutputStream output) in C:\NHProf\HibernatingRhinos.NHibernate.Profiler.Messages.cs:line 1830
   at Google.ProtocolBuffers.CodedOutputStream.WriteMessage(Int32 fieldNumber, IMessage value) in C:\OSS\Buffy\ProtocolBuffers\CodedOutputStream.cs:line 222
   at Google.ProtocolBuffers.MessageStreamWriter`1.Write(T message) in C:\OSS\Buffy\ProtocolBuffers\MessageStreamWriter.cs:line 26
   at HibernatingRhinos.NHibernate.Profiler.Appender.NHibernateProfilerAppender.WriteToProfilerWithRetries(IEnumerable`1 wrappers, Int32 retryCount) in C:\NHProf\NHibernateProfilerAppender.cs:line 150

Ah ha! I thought, I know what is wrong, "select() is broken”. With that in mind, I looked at the relevant source file, and tried to figure out what the bug was. Here are the relevant sections:

image

image

Looking at that piece of code, it was very clear where the error was. Do you see it?

I won’t blame you if you don’t, the error is clear because it is not there. This is perfectly legal code, with no option for errors. Since we did get an error, it is clear that something is broken. And the problem is at a higher level. Usually, in such scenarios, it is a race condition that cause a violation of invariants. And that is the case here. Looking at the code, it was clear what the problem was, I was synchronizing access to the stream, but I wasn’t synchronizing access to the writer.

In this case, we actually got a real error, that pointed me very quickly to the real issue. In most scenarios, what actually happened was silent data corruption at the write end, which I interpreted as problems with the use of the unreliable network.

Again, yuck, and I feel really stupid.

Can you make money on OSS tooling in the .NET world?

The answer is yes. Here is a chart of downloads and orders of NH Prof.

image

I am fairly happy with the way NH Prof sells. I think it could be better, but I want to see what happens to sales when I release the v1.0 version (which will be soon).

Nitpicker corner: Numbers has been removed from the chart for a reason.

Waiting, it isn’t as simple as twiddling your thumbs

Just thought that it would be interesting post to talk about the evolution of a single method. This is used solely for the integration tests, by the way.

public void WaitForAllMessages()
{ 
  while (mailBox.IsEmpty == false)
  {
    Thread.Sleep(100);
  }
}

It started its life very simply, as just a method that waited until the mailbox was empty. But then we run into a problem, sometimes the method returned while a message was being processed, and that caused the tests to fail.

Then we had this:

public void WaitForAllMessages()
{ 
  while (mailBox.IsEmpty == false  || currentlyProcessingMessages > 0)
  {
    Thread.Sleep(100);
  }
}

There are other pieces of the code, that update the currentlyProcessingMessages piece, but it isn’t really interesting. Some time passed, and we run into additional issues, which led to this beast:

public void WaitForAllMessages()
{
    // we wait in case there are additional messages that have not yet arrived
    // to the listner. We arbitrarily define that if we wait for 5 consecutive 
    // times with no new messages, there are no more messages
    int countOfTimesTriesToWaitAndThereWereNoMessages = 0;
    while(countOfTimesTriesToWaitAndThereWereNoMessages < 5)
    {
          if (WaitForAllMessagesInMemoryQueueOrProcessing())
            countOfTimesTriesToWaitAndThereWereNoMessages = 0;
        else
              countOfTimesTriesToWaitAndThereWereNoMessages += 1;
          Thread.Sleep(100);
    }
}

private bool WaitForAllMessagesInMemoryQueueOrProcessing()
{
    bool waited = false;
    while (mailBox.IsEmpty == false ||
           currentlyProcessingMessages > 0)
    {
        waited = true;
        Thread.Sleep(100);
    }
    return waited;
}

And that is where we are now.

NH Prof New Feature: Detecting 2nd cache collection loads

I noticed the lack when I was teaching the Core NHibernate course. While NH Prof was able to detect loading of an entity from the second level cache and the loading of query from the query cache, it wouldn’t show when we were loading a collection from the collection cache.

That was actually quite easy to fix :-)

Take a look:

image

This feature is now available on Build 277 and up.

Have fun, and happy cache tracing :-)

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 ask two things out of you:

  • Register yourself as an NHibernate user in ohloh by clicking this link:
  • And please register your experience with NHibernate in our Success Stories page.

This is not a lot to ask, I feel, and it would make the NHibernate team feel much more appreciated.

Thanks…

Tags:

Published at

Originally posted at

Comments (17)

Can you justify your actions with regards to this pattern?

image

Probably the most common problem with unintended complexity in software is the unthinking application of patterns. I see a lot more code that has became more complex through that practice than code that has became simpler.

David Wheeler said: “All problems in computer science can be solved by another level of indirection;” However, we tend to forget the extra bit that Kevlin Henney's tacked at the end, "...except for the problem of too many layers of indirection."

Most patterns templates come with a clearly defined sections for “when to use” and “what are the disadvantages”. The problem is that patterns has became hip and cool, so people are actively seeking to use them.

Memento is my favorite pattern.

Do you know why?

I have never had found any need to implement it.

Remember, patterns are just formalized ways to work around limitations in the programming language or environment. Despite all the coolness points associated with them, they represent a non trivial cost in time, complexity and implications on a code base.

When you use a pattern, you have to be able to justify that use. What does it buy you? Have you considered the ramifications? What does it cost you? Is it worth it?  I tend to use patterns quite a bit, but in the last year or so I force myself to make a conscious decision whenever I want to apply one. Quite often, there is nothing that really requires it.

If you can get by without patterns, it usually means that you have a simpler solution. If you have a problem that fits a pattern’s problem description, and the pattern is applicable for your programming language and environment, you should use it.

Just don’t apply patterns all over the place, it end up being an overly engineered codebase that has significant maintenance overhead because of the patterns. I have seen too many apps that could have been simple turn into a multi layer mess of indirect calls that no one could really follow.

When I was in the army, I usually follow the following maxim:

Think, then do. And you have better be able to explain you actions.

It worked for me then and since.

The state of Open Source in the .NET ecosystem: A five year summary

I have been forcibly reminded lately that I have been doing this for quite some time. In fact, I have been doing working with Open Source on the .Net platform for over 5 years now. And a few conversations with friends have given me quite a retrospective on the state of OSS.Net.

5 years ago, it was 2004, .Net 1.1 was still a hot thing, and Stored Procedures on top of datasets where still a raging debate. Open source was considered a threat and Steve Balmer was busy blasting at any OSS project that showed up. The very existence or need for OSS on the .NET platform was frequently questioned.

I remember trying to find work in 2005, after over a year of actively working on Open Source projects and with Rhino Mocks making steady but sure progress in the .NET TDD community and not being able to leverage that experience into job interviews. It was only commercial experience that counted for the gate keepers.

The last 5 years have been quite interesting in the .NET ecosystem from the OSS world. It has gotten to the point where the use of OSS tools, frameworks and platforms is no longer a strange exception, but is quite common place.

There are several data points on which I am basing this statement:

  • Books about OSS projects are commonly published.
  • Microsoft is doing a lot to encourage OSS on the .Net platform.
  • NHibernate’s download numbers are consistently above ten thousands a month, usually closer or above twenty thousands a month.
  • I released Windsor 2.0 not even two weeks ago, and it has over 1,200 downloads already.
  • The number of messages to the NHibernate users mailing list is usually above a thousands per month.
  • My NHibernate course sold out and I have to do a repeat course to satisfy demand.

And then, there is my own experience, both as a member in the community and as a consultant. I see OSS being used quite often. A lot of my engagements are about OSS tools and framework, and I am rarely the person to introduce them into the company.

I think that there are several factors playing around here, but most of that is around maturity. The OSS players in the .NET world had had some time to work on things, and most established projects have been around for years. NHibernate is 6 years old, Castle is 5, Rhino Mocks 4. It is not the Open Source world that represent stability. With Microsoft replacing their data access strategy every two years, it might be best to use NHibernate, because it has been around for a long time already.

There is also the issue of maturity in the ecosystem itself. It has became quite clear that it is acceptable and even desirable to use OSS projects. And we have companies making explicit decisions to support Open Source projects (iMeta decision to donate 3 dev months is just one example, although the most prominent one). Recently I was working with a client on strategies for Open Sourcing their software, and how to manage a good Open Source project. In another client, a decision has been reached to put all the infrastructure stuff as Open Source, even newly developed one, because they are infrastructure. Infrastructure is seen as a commodity, and as such, there is little value in trying to make it unique.

There is a lot of value, however, in making it Open Source and accepting improvements from others. And I was able to point out to that client how outside contributions to the infrastructure has enabled us to do things that we would have to do ourselves.

Things are changing, I don’t think that we are at the balance point yet, but I think that we are seeing a very big shift, happening very very slowly. And from the Open Source perspective, things are looking quite good.

Dev Teach Vancouver & ALT.Net Canada

In a very few weeks, I am going to spend some time in my favorite north America conference, DevTeach. It is my favorite for several reason, great attendees, great organization, great speakers line up, and an always interesting occurrences. Thankfully, no one published the real pictures from the last one :-)

This time, in addition to all the nice features that are usually part of DevTeach, we also have the bonus of having ALT.Net Canada happening in the weekend directly after DevTeach. This means that I am going to be having throughout the week.

As an aside, I am going to stay a day or two after the weekend is over, the original plan was to give me some time to recover from all of that, but if you are in Vancouver and would like me to drop in and do some consulting, do ping me.

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:

image

I am going to present three things for each physical data model manifestation. The mapping, the database schema and the result of the following query:

s.CreateQuery("from Owner owner where owner.Name = 'ayende'")
    .List<Owner>();

We will start with the classic, table per class, which looks like this:

<class name="Company">
    <id column="Id"  type="System.Int32">
        <generator class="hilo"/>
    </id>
    <property name="Name"/>
    <property name="CompanyRegistrationId"/>
    <set name="Horses" table="CompanyHorses">
        <key column="Company"/>
        <many-to-many class="Horse" column="Horse"/>
    </set>
</class>

<class name="Individual">
    <id column="Id"  type="System.Int32">
        <generator class="hilo"/>
    </id>
    <property name="Name"/>
    <property name="Email"/>
    <set name="Horses" table="HorsesBelongToIndividuals">
        <key column="Company"/>
        <many-to-many class="Horse" column="Horse"/>
    </set>
</class>

<class name="Consortium">
    <id column="Id"  type="System.Int32">
        <generator class="hilo"/>
    </id>
    <property name="Name"/>
    <set name="Horses" table="HorsesBelongToIndividuals">
        <key column="Company"/>
        <many-to-many class="Horse" column="Horse"/>
    </set>
    <set name="Owners" table="ConsortiumOwners">
        <key column="Consortium"/>
        <many-to-any id-type="System.Int32" meta-type="System.String">
            <meta-value class="Individual" value="Individual"/>
            <meta-value class="Company" value="Company"/>
            <meta-value class="Consortium" value="Consortium"/>
            <column name="OwnerType"/>
            <column name="OwnerId"/>
        </many-to-any>
    </set>
</class>

The database schema is:

image

You might want to pay some attention to the association between Consortium and its owner, using <many-to-any/>.

Trying to execute the aforementioned query will give us an error, NHibernate is not aware of any persistent class called Owner and HQL queries are not polymorphic over unknown types. Criteria API, however, are. And we can execute the following query successfully:

s.CreateCriteria<Owner>()
    .Add(Restrictions.Eq("Name", "ayende"))
    .List<Owner>();

Which result in:

image

image

image

Let us look at another scenario, which would keep the same data model, but let NHibernate know about the inheritance association between the classes. NHibernate call this type of association union subclasses. Here are the mapping:

<class name="Owner" abstract="true">
    <id column="Id"  type="System.Int32">
        <generator class="hilo"/>
    </id>
    <set name="Horses" table="OwnerHorses">
        <key column="Owner"/>
        <many-to-many class="Horse" column="Horse"/>
    </set>
    <property name="Name"/>
    <union-subclass name="Company">
        <property name="CompanyRegistrationId"/>
    </union-subclass>

    <union-subclass  name="Individual">
        <property name="Email"/>
    </union-subclass>

    <union-subclass name="Consortium">
        <set name="Owners" table="ConsortiumOwners">
            <key column="Consortium"/>
            <many-to-many class="Owner" column="Owner"/>
        </set>
    </union-subclass>
</class>

You might notice how simple the mapping looks like. For that matter, look at how we could simplify the mapping between horses and owners.

image

The resulting query is… interesting:

image

And now let us move to the more classic inheritance schemes, first, let us look at table per hierarchy:

<class name="Owner" abstract="true">
    <id column="Id"  type="System.Int32">
        <generator class="hilo"/>
    </id>
    <discriminator column="Type" type="System.String"/>
    <set name="Horses" table="OwnerHorses">
        <key column="Owner"/>
        <many-to-many class="Horse" column="Horse"/>
    </set>
    <property name="Name"/>
    <subclass discriminator-value="Company" name="Company">
        <property name="CompanyRegistrationId"/>
    </subclass>

    <subclass discriminator-value="Individual" name="Individual">
        <property name="Email"/>
    </subclass>

    <subclass discriminator-value="Consortium" name="Consortium">
        <set name="Owners" table="ConsortiumOwners">
            <key column="Consortium"/>
            <many-to-many class="Owner" column="Owner"/>
        </set>
    </subclass>
</class>

With the following schema:

image

In this case, Owner.Type is the discriminator for the Owner hierarchy. And the query that is generated is:

image

And finally, we have table per subclass, which we use the following mapping:

<class name="Owner" abstract="true">
    <id column="Id"  type="System.Int32">
        <generator class="hilo"/>
    </id>
    <set name="Horses" table="OwnerHorses">
        <key column="Owner"/>
        <many-to-many class="Horse" column="Horse"/>
    </set>
    <property name="Name"/>
    <joined-subclass name="Company">
        <key column="Id"/>
        <property name="CompanyRegistrationId"/>
    </joined-subclass>

    <joined-subclass name="Individual">
        <key column="Id"/>
        <property name="Email"/>
    </joined-subclass>

    <joined-subclass name="Consortium">
        <key column="Id"/>
        <set name="Owners" table="ConsortiumOwners">
            <key column="Consortium"/>
            <many-to-many class="Owner" column="Owner"/>
        </set>
    </joined-subclass>
</class>

This gives us this schema:

image

Using this approach, we query them using:

image

I would like to point out that this is just a sample of the type of things that we can do with NHibernate, and that I took the easy path doing so. There are actually more complex inheritance option available (discriminator with joined classes, for example) and it is pretty easy to change things even further.

And, of course, it is entirely possible to take things in the other direction, and have a single physical data model that can map to several domain models.

Have fun…

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:

image

Let us find a blog by its identifier:

var blog = s.Get<Blog>(1);

Which results in:

image

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 here.

Now, let us try to search by a property:

var blogs = s.CreateCriteria<Blog>()
.Add(Restrictions.Eq("Title", "Ayende @ Rahien"))
.List<Blog>();

Which results in:

image

If we try to make the same with HQL, it would look:

var blogs = s.CreateQuery("from Blog b where b.Title = :title")
.SetParameter("title","Ayende @ Rahien")
.List<Blog>();

Which results in slight different SQL than using the criteria:

image 

What about trying a more complex conditional? Let us try to see comparing two properties:

var blogs = s.CreateCriteria<Blog>()
.Add(Restrictions.Eq("Title","Ayende @ Rahien"))
.Add(Restrictions.Eq("Subtitle", "Send me a patch for that"))
.List<Blog>();

Which results in:

image

Let us do that again, but using two properties using an OR:

var blogs = s.CreateCriteria<Blog>()
.Add(Restrictions.Disjunction()
.Add(Restrictions.Eq("Title", "Ayende @ Rahien"))
.Add(Restrictions.Eq("Subtitle", "Send me a patch for that")))
.List<Blog>();

Which would result in:

image

We can also execute the same SQL using the following syntax:

var blogs = s.CreateCriteria<Blog>()
.Add(
Restrictions.Eq("Title", "Ayende @ Rahien") ||
Restrictions.Eq("Subtitle", "Send me a patch for that")
)
.List<Blog>();

Doing the same using HQL would be:

var blogs = s.CreateQuery("from Blog b where b.Title = :title and b.Subtitle = :subtitle")
.SetParameter("title","Ayende @ Rahien")
.SetParameter("subtitle", "Send me a patch for that")
.List<Blog>();

Which results in:

image

And changing that to an OR is pretty self explanatory :-)

var blogs = s.CreateQuery("from Blog b where b.Title = :title or b.Subtitle = :subtitle")
.SetParameter("title","Ayende @ Rahien")
.SetParameter("subtitle", "Send me a patch for that")
.List<Blog>();

Giving us:

image

Let us try something a bit more complex, finding a blog by a post title:

var blogs = s.CreateCriteria<Blog>()
.CreateCriteria("Posts")
.Add(Restrictions.Eq("Title","NHibernate Rocks"))
.List<Blog>();

That gives us:

image

You will note that we force a load of the Posts collection. We can try something else, though:

var blogs = s.CreateCriteria<Blog>()
.Add(Subqueries.PropertyIn("id",
DetachedCriteria.For<Post>()
.Add(Restrictions.Eq("Title","NHibernate Rocks"))
.SetProjection(Projections.Property("Blog.id"))
))
.List<Blog>();

Which would give us the same result, but without loading the Posts collection:

image

This is a pretty common example of changing the way that we compute complex conditionals when we want to avoid wide result sets.

Let us do the same with HQL:

var blogs = s.CreateQuery("from Blog b join b.Posts p where p.Title = :title")
.SetParameter("title", "NHibernate Rocks")
.List<Blog>();

Which would result:

image

We have the same issue as with the first Criteria API, and we can resolve it in the same way:

var blogs = s.CreateQuery("from Blog b where b.id in (from Post p where p.Title = :title)")
.SetParameter("title", "NHibernate Rocks")
.List<Blog>();

And the same result as in the Criteria API show us:

image

And the final test, let us try to find a blog that has a post posted by a specific user:

var blogs = s.CreateCriteria<Blog>()
.Add(Subqueries.PropertyIn("id",
DetachedCriteria.For<Post>()
.SetProjection(Projections.Property("Blog.id"))
.CreateCriteria("User")
.Add(Restrictions.Eq("Username","Ayende"))
))
.List<Blog>();

And this give us:

image

The same thing with HQL will give us:

var blogs = s.CreateQuery("from Blog b where b.id in (from Post p where p.User.Username = :user)")
.SetParameter("user","Ayende")
.List<Blog>();

And that results:

image

Tags:

Published at

Originally posted at

Comments (16)

Who is the responsible party?

Object Oriented design is all about placing behavior and data together, of making the object responsible for its own operations. The problem then becomes identifying which object is responsible for what. This is usually pretty easy, since the natural owner of an operation is usually clear. Note that I don’t much care for the choice people make between things like parent.AddChild(child) vs. child.AddTo(parent). Both are equally good from my point of view. What I don’t want to see is this:

parent.Children.Add(child);
child.Parent = parent;

The reason for that is quite simple. This is a serious violation of the Tell, Don’t Ask protocol, and it means that someone is missing the pointing between the ownership of a particular operation and the instigator of that operation. The instigator is usually the UI, requesting that something will happen. Bad code will usually put a lot of the logic in the instigator side, rather than on the owner side.

Then we move into issues of cohesiveness and coupling, which guides us further in understanding how to place the appropriate responsibilities. All logic related to a particular aspect of the application should reside in the same location, so it is easy to work with, modify and change.

But by far the most common error I see people make is placing responsibilities on the instigator rather than on other parts of the system. There should be a very clear distinction between the two. Other than that, there is a lot of stuff that is just experience and understanding of the actual system.

In the end, all systems are refactorable, so you shouldn’t be afraid to make mistakes.

NH Prof: Release Candidate is out

image Well,

After quite a while of developing on a private branch, it is time to make NH Prof RC public. We have worked on several new features, but chief among them was performance. As I outlined in the past, we have to rip apart the internal communication mechanisms inside NH Prof, to allow it to react well under high load.

There are some things that you need to know first, though:

  • Session factory stats is currently disabled, there is no reason except that some things had to be cut in order to release the RC. It will be back soon.
  • The RC bits are not compatible with the beta bits. If you want to use RC UI with your application (and you should), you need to use the RC appender.

As usual, you can find it here, build 260 or up.

Have fun, and tell us what you think.

Mutable Linq Expressions

As you probably know, System.Linq.Expression is considered to be immutable. This is a major pain when it comes to working with them, and many Linq providers end up creating a parallel hierarchy of expressions that are mutable.

What I am going to show you now is probably going to get some people in Microsoft pretty angry with me, but hey, if they used ReSharper, they wouldn’t have this problem. In a true TDD fashion, let us start with a failing test:

var constant = Expression.Constant(5);
var captureReference = constant;

// put something here that may not change the captureReference variable

Debug.Assert(ReferenceEquals(constant, captureReference));
Debug.Assert(constant.Value.Equals(2));

We then move on to look at the actual ConstantExpression code:

image

Do you see the hook that I am going to plug into?

Coming back to my ReSharper plug, it is pretty easy to see that value is a read only value, but it is not mark as such. This is one of ReSharper’s suggestions that came in 4.0, and made me aware of the reasons to do so. Because it is not mark as such, I have a way in…

All it requires is a bit of LCG (lightweight code generation), such as this:

public static Action<ConstantExpression, object> CreateSetAccessor()
{
    var accessor = new DynamicMethod("SetValue", typeof (void), new Type[]
    {
        typeof (ConstantExpression),
        typeof (object)
    }, true);
    var generator = accessor.GetILGenerator();
    generator.Emit(OpCodes.Ldarg_0);
    generator.Emit(OpCodes.Ldarg_1);
    generator.Emit(OpCodes.Stfld,typeof(ConstantExpression).GetField("value",BindingFlags.Instance|BindingFlags.NonPublic));
    generator.Emit(OpCodes.Ret);
    return (Action<ConstantExpression, object>)accessor.CreateDelegate(typeof(Action<ConstantExpression,object>));
}

And now we have a passing test:

var valueSetAccessor = CreateSetAccessor();
var constant = Expression.Constant(5);
var captureReference = constant;

valueSetAccessor(constant, 2);

Debug.Assert(ReferenceEquals(constant, captureReference));
Debug.Assert(constant.Value.Equals(2));

Now, I don’t really recommend doing this. This is unsupported, etc.

But it is a cool trick, and it applies pretty much generically across all of the Expression classes.

NH Prof for Hibernate – Now in Closed Beta

Well, I heard the requirement quite clearly, so let us see how this looks like, given the following code:

public class SelectBlogByIdUsingCriteria extends AbstractScenario {

    @Override
    protected void doExecute(SessionFactory factory) {
        doInTransaction(new SessionCallback<Object>() {
            @Override
            public Object execute(Session session) {
                return session.createCriteria(Blog.class)
                .add(Restrictions.idEq(1))
                .list();            
            }
        });

    }
}

We get the following result:

image

I am currently looking for people to actually do field testing of this for me.

If you are interested, please ping me via email.