NHibernate

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

posted @ Tuesday, June 23, 2009 11:37 AM | Feedback (21)

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.

posted @ Tuesday, June 23, 2009 11:28 AM | Feedback (12)

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

posted @ Thursday, June 11, 2009 5:40 PM | Feedback (17)

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

posted @ Wednesday, June 10, 2009 8:40 PM | Feedback (24)

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

posted @ Monday, June 08, 2009 7:03 PM | Feedback (10)

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

posted @ Saturday, June 06, 2009 3:13 PM | Feedback (29)

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

posted @ Thursday, June 04, 2009 2:20 AM | Feedback (21)

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

posted @ Wednesday, June 03, 2009 1:52 AM | Feedback (20)

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

posted @ Tuesday, June 02, 2009 1:32 AM | Feedback (13)

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

posted @ Monday, June 01, 2009 11:13 AM | Feedback (14)

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

posted @ Sunday, May 31, 2009 11:04 PM | Feedback (5)

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

posted @ Saturday, May 30, 2009 10:55 PM | Feedback (35)

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

posted @ Friday, May 29, 2009 10:40 PM | Feedback (6)

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

posted @ Thursday, May 28, 2009 11:49 PM | Feedback (15)

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

posted @ Monday, May 25, 2009 10:05 PM | Feedback (12)

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

posted @ Friday, May 22, 2009 12:00 AM | Feedback (17)

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

posted @ Tuesday, May 19, 2009 11:03 AM | Feedback (10)

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

posted @ Tuesday, May 19, 2009 8:57 AM | Feedback (16)

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…

posted @ Monday, May 18, 2009 11:47 PM | Feedback (2)

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

posted @ Monday, May 04, 2009 10:33 AM | Feedback (8)

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

posted @ Sunday, May 03, 2009 10:49 PM | Feedback (19)

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

posted @ Saturday, May 02, 2009 10:34 AM | Feedback (13)

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. :-)...

posted @ Friday, May 01, 2009 10:28 AM | Feedback (17)

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

posted @ Thursday, April 30, 2009 8:55 AM | Feedback (25)

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

posted @ Wednesday, April 29, 2009 5:04 PM | Feedback (30)

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

posted @ Tuesday, April 28, 2009 9:32 AM | Feedback (36)

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

posted @ Monday, April 27, 2009 7:33 AM | Feedback (20)

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

posted @ Friday, April 24, 2009 2:28 PM | Feedback (3)

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

posted @ Thursday, April 23, 2009 6:11 AM | Feedback (6)

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

posted @ Wednesday, April 22, 2009 7:56 PM | Feedback (23)

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

posted @ Wednesday, April 22, 2009 5:52 AM | Feedback (12)

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

posted @ Tuesday, April 21, 2009 5:29 AM | Feedback (18)

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

posted @ Monday, April 20, 2009 3:56 AM | Feedback (10)

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

posted @ Sunday, April 19, 2009 3:31 AM | Feedback (15)

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

posted @ Saturday, April 18, 2009 4:05 PM | Feedback (15)

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

posted @ Friday, April 17, 2009 7:03 PM | Feedback (76)

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

posted @ Friday, April 17, 2009 12:55 AM | Feedback (10)

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

posted @ Thursday, April 16, 2009 12:47 AM | Feedback (7)

NHibernate Mapping - Concurrency

NHibernate has several concurrency models that you can use: None Optimistic Dirty All Versioned Numeric Timestamp DB timestamp Pessimistic ...

posted @ Wednesday, April 15, 2009 12:40 AM | Feedback (26)

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

posted @ Monday, April 13, 2009 11:01 PM | Feedback (13)

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

posted @ Saturday, April 11, 2009 7:23 AM | Feedback (16)

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

posted @ Thursday, April 09, 2009 5:22 AM | Feedback (21)

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

posted @ Wednesday, April 08, 2009 4:20 PM | Feedback (23)

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

posted @ Tuesday, April 07, 2009 6:23 PM | Feedback (16)

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

posted @ Sunday, March 22, 2009 4:21 PM | Feedback (4)

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

posted @ Friday, March 20, 2009 12:32 PM | Feedback (8)

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

posted @ Sunday, February 22, 2009 9:00 PM | Feedback (15)

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.

posted @ Sunday, February 15, 2009 6:35 AM | Feedback (18)

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

posted @ Saturday, January 17, 2009 3:18 PM | Feedback (1)

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

posted @ Saturday, January 10, 2009 2:19 AM | Feedback (12)

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

posted @ Tuesday, December 30, 2008 6:16 PM | Feedback (0)

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

posted @ Monday, December 29, 2008 9:47 PM | Feedback (2)

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

posted @ Monday, December 29, 2008 7:51 AM | Feedback (9)

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

posted @ Sunday, December 28, 2008 10:21 PM | Feedback (13)

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()) { ...

posted @ Sunday, December 28, 2008 10:05 PM | Feedback (18)

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

posted @ Thursday, December 11, 2008 8:22 AM | Feedback (20)

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; } ...

posted @ Sunday, December 07, 2008 5:09 AM | Feedback (0)

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!

posted @ Wednesday, December 03, 2008 7:12 PM | Feedback (11)

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?

posted @ Tuesday, December 02, 2008 12:58 AM | Feedback (12)

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

posted @ Monday, December 01, 2008 10:35 AM | Feedback (1)

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

posted @ Monday, December 01, 2008 8:03 AM | Feedback (19)

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

posted @ Wednesday, November 26, 2008 2:17 AM | Feedback (6)

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

posted @ Wednesday, November 26, 2008 2:03 AM | Feedback (4)

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

posted @ Tuesday, November 25, 2008 8:06 PM | Feedback (0)

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

posted @ Tuesday, November 25, 2008 7:05 PM | Feedback (1)

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!

posted @ Saturday, November 22, 2008 8:52 PM | Feedback (15)

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

posted @ Thursday, November 13, 2008 9:07 PM | Feedback (20)

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

posted @ Wednesday, November 12, 2008 7:14 PM | Feedback (2)

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

posted @ Thursday, November 06, 2008 5:04 PM | Feedback (2)

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

posted @ Thursday, November 06, 2008 5:34 AM | Feedback (4)

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

posted @ Tuesday, November 04, 2008 8:16 AM | Feedback (44)

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

posted @ Saturday, November 01, 2008 6:01 PM | Feedback (52)

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.

posted @ Friday, October 31, 2008 5:35 PM | Feedback (1)

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.

posted @ Wednesday, October 29, 2008 12:41 PM | Feedback (19)

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.

posted @ Thursday, October 23, 2008 10:59 AM | Feedback (13)

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

posted @ Wednesday, October 22, 2008 8:42 PM | Feedback (8)

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

posted @ Tuesday, October 21, 2008 9:10 PM | Feedback (18)

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

posted @ Thursday, October 16, 2008 12:17 AM | Feedback (19)

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

posted @ Wednesday, October 15, 2008 11:45 PM | Feedback (13)

Do you think that I have a heavy weight build process?

posted @ Wednesday, October 15, 2008 4:54 PM | Feedback (9)

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.

posted @ Monday, October 13, 2008 1:42 PM | Feedback (4)

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

posted @ Monday, October 13, 2008 1:19 AM | Feedback (8)

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

posted @ Saturday, October 11, 2008 12:00 AM | Feedback (3)

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

posted @ Friday, October 10, 2008 2:19 AM | Feedback (8)

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

posted @ Thursday, October 09, 2008 1:31 AM | Feedback (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.

posted @ Saturday, October 04, 2008 7:15 PM | Feedback (23)

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

posted @ Thursday, September 11, 2008 6:06 AM | Feedback (15)

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

posted @ Tuesday, August 26, 2008 5:06 AM | Feedback (15)

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

posted @ Monday, August 25, 2008 5:35 PM | Feedback (7)

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!

posted @ Saturday, August 23, 2008 6:38 PM | Feedback (27)

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

posted @ Tuesday, August 12, 2008 4:51 PM | Feedback (12)

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

posted @ Thursday, August 07, 2008 2:14 AM | Feedback (8)

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

posted @ Thursday, July 31, 2008 4:11 PM | Feedback (48)

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

posted @ Friday, July 25, 2008 10:30 AM | Feedback (15)

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

posted @ Thursday, July 24, 2008 11:38 PM | Feedback (16)

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

posted @ Monday, July 21, 2008 2:23 PM | Feedback (7)

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

posted @ Sunday, July 13, 2008 12:06 PM | Feedback (1)

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.

posted @ Monday, June 30, 2008 12:48 AM | Feedback (12)

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

posted @ Tuesday, May 06, 2008 11:48 AM | Feedback (3)

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) { ...

posted @ Thursday, May 01, 2008 1:21 PM | Feedback (8)

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.

posted @ Friday, April 04, 2008 5:54 PM | Feedback (15)

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

posted @ Monday, March 31, 2008 9:31 AM | Feedback (30)

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

posted @ Thursday, March 27, 2008 11:16 AM | Feedback (12)

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.

posted @ Friday, March 21, 2008 6:30 AM | Feedback (4)

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.

posted @ Sunday, February 17, 2008 2:25 PM | Feedback (1)

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

posted @ Saturday, February 16, 2008 10:16 PM | Feedback (23)

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

posted @ Thursday, January 24, 2008 4:24 PM | Feedback (4)

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

posted @ Thursday, January 24, 2008 1:20 PM | Feedback (2)

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):...

posted @ Thursday, January 24, 2008 1:57 AM | Feedback (8)

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

posted @ Thursday, January 24, 2008 12:59 AM | Feedback (21)

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

posted @ Tuesday, January 22, 2008 1:49 AM | Feedback (24)

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!

posted @ Tuesday, January 15, 2008 7:29 AM | Feedback (4)

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

posted @ Saturday, January 12, 2008 9:13 AM | Feedback (7)

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"; } ...

posted @ Friday, January 11, 2008 4:38 PM | Feedback (3)

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

posted @ Sunday, December 23, 2007 11:05 PM | Feedback (3)

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

posted @ Wednesday, November 14, 2007 1:12 AM | Feedback (8)

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

posted @ Tuesday, November 13, 2007 12:53 AM | Feedback (22)

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

posted @ Sunday, November 04, 2007 11:09 PM | Feedback (0)

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

posted @ Friday, October 26, 2007 3:57 AM | Feedback (18)

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

posted @ Tuesday, October 23, 2007 3:12 PM | Feedback (23)

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",...

posted @ Tuesday, October 23, 2007 12:56 PM | Feedback (2)

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

posted @ Monday, October 15, 2007 10:43 PM | Feedback (5)

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

posted @ Friday, October 12, 2007 11:02 AM | Feedback (10)

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; "; } }

posted @ Tuesday, October 09, 2007 5:37 PM | Feedback (13)

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

posted @ Saturday, September 29, 2007 4:28 PM | Feedback (16)

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

posted @ Sunday, September 09, 2007 10:49 PM | Feedback (8)

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

posted @ Thursday, August 30, 2007 4:43 PM | Feedback (6)

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

posted @ Sunday, August 26, 2007 9:04 PM | Feedback (3)

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

posted @ Sunday, August 26, 2007 8:56 PM | Feedback (7)

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

posted @ Sunday, August 26, 2007 1:23 AM | Feedback (9)

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

posted @ Sunday, August 12, 2007 4:37 PM | Feedback (4)

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

posted @ Saturday, August 11, 2007 9:38 PM | Feedback (12)

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

posted @ Saturday, August 11, 2007 6:54 AM | Feedback (2)

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

posted @ Thursday, June 28, 2007 7:00 PM | Feedback (1)

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

posted @ Monday, June 25, 2007 7:05 PM | Feedback (9)

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

posted @ Monday, June 25, 2007 1:08 AM | Feedback (5)

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

posted @ Sunday, June 24, 2007 9:04 AM | Feedback (4)

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

posted @ Friday, June 22, 2007 12:15 PM | Feedback (25)

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

posted @ Thursday, June 21, 2007 6:33 AM | Feedback (7)

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

posted @ Tuesday, June 05, 2007 11:53 PM | Feedback (10)

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

posted @ Tuesday, June 05, 2007 12:00 AM | Feedback (6)

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

posted @ Monday, June 04, 2007 4:48 PM | Feedback (3)

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

posted @ Sunday, June 03, 2007 1:15 AM | Feedback (31)

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

posted @ Sunday, June 03, 2007 12:03 AM | Feedback (6)

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

posted @ Saturday, June 02, 2007 10:55 PM | Feedback (13)

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

posted @ Saturday, June 02, 2007 12:09 AM | Feedback (6)

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

posted @ Tuesday, May 29, 2007 12:10 AM | Feedback (4)

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

posted @ Sunday, May 27, 2007 8:38 PM | Feedback (5)

NHibernate & WCF

Just to reference a great article about using NHibernate & WCF, worth checking out.

posted @ Sunday, May 27, 2007 1:06 AM | Feedback (1)

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

posted @ Sunday, May 27, 2007 12:51 AM | Feedback (1)

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

posted @ Sunday, May 20, 2007 11:24 AM | Feedback (8)

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")] ...

posted @ Thursday, May 10, 2007 11:57 PM | Feedback (7)

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.

posted @ Thursday, May 10, 2007 10:37 PM | Feedback (0)

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

posted @ Wednesday, May 09, 2007 6:33 PM | Feedback (15)

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

posted @ Tuesday, May 08, 2007 10:56 PM | Feedback (12)

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

posted @ Friday, May 04, 2007 9:50 PM | Feedback (12)

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

posted @ Friday, May 04, 2007 3:41 AM | Feedback (3)

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.

posted @ Friday, May 04, 2007 3:28 AM | Feedback (0)

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.

posted @ Tuesday, May 01, 2007 11:00 PM | Feedback (0)

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

posted @ Friday, April 27, 2007 7:44 PM | Feedback (3)

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

posted @ Tuesday, April 24, 2007 11:21 AM | Feedback (8)

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

posted @ Saturday, April 21, 2007 3:06 AM | Feedback (8)

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

posted @ Tuesday, April 17, 2007 11:31 AM | Feedback (7)

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

posted @ Saturday, April 14, 2007 2:19 AM | Feedback (1)

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

posted @ Tuesday, April 10, 2007 3:24 AM | Feedback (0)

Linq For NHibernate: More Implementation Details

Bobby Diaz did some more work recently, and has documented it here. Interesting reading...

posted @ Thursday, April 05, 2007 5:05 AM | Feedback (0)

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.

posted @ Monday, April 02, 2007 3:10 PM | Feedback (4)

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

posted @ Thursday, March 29, 2007 11:31 AM | Feedback (2)

Tomorrow on Dot Net Rocks: Oren Eini On nHibernate and RhinoMocks!

Be sure to listen, it was a very interesting discussion.

posted @ Wednesday, March 28, 2007 10:53 PM | Feedback (0)

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

posted @ Tuesday, March 27, 2007 11:00 PM | Feedback (0)

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.

posted @ Tuesday, March 27, 2007 8:32 PM | Feedback (2)

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

posted @ Monday, March 26, 2007 10:31 AM | Feedback (7)

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

posted @ Friday, March 23, 2007 12:57 PM | Feedback (1)

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.

posted @ Tuesday, March 20, 2007 9:58 AM | Feedback (4)

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.

posted @ Tuesday, March 20, 2007 9:55 AM | Feedback (5)

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

posted @ Tuesday, March 20, 2007 2:08 AM | Feedback (10)

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

posted @ Monday, March 19, 2007 11:10 PM | Feedback (0)

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

posted @ Sunday, March 18, 2007 3:04 PM | Feedback (5)

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>()) { ...

posted @ Saturday, March 17, 2007 9:24 PM | Feedback (3)

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

posted @ Saturday, March 17, 2007 6:55 PM | Feedback (14)

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

posted @ Saturday, March 17, 2007 6:53 PM | Feedback (14)

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

posted @ Friday, March 16, 2007 2:12 PM | Feedback (19)

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

posted @ Wednesday, February 28, 2007 9:11 AM | Feedback (14)

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.

posted @ Sunday, January 28, 2007 9:30 AM | Feedback (5)

Watch me on DNR-TV

You can find the episode here, I am going to watch it now, more later...

posted @ Friday, January 26, 2007 12:43 AM | Feedback (3)

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;

posted @ Monday, January 08, 2007 9:02 PM | Feedback (0)

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

posted @ Saturday, January 06, 2007 1:46 PM | Feedback (1)

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

posted @ Sunday, December 31, 2006 4:16 PM | Feedback (0)

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.

posted @ Saturday, December 30, 2006 4:19 PM | Feedback (3)

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

posted @ Wednesday, December 27, 2006 8:10 PM | Feedback (1)

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

posted @ Tuesday, December 26, 2006 7:21 PM | Feedback (8)

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

posted @ Thursday, December 14, 2006 10:24 AM | Feedback (0)

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

posted @ Sunday, December 10, 2006 8:47 PM | Feedback (9)

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

posted @ Thursday, December 07, 2006 5:57 PM | Feedback (0)

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

posted @ Thursday, December 07, 2006 8:09 AM | Feedback (12)

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

posted @ Tuesday, December 05, 2006 8:39 AM | Feedback (2)

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

posted @ Saturday, December 02, 2006 9:10 AM | Feedback (3)

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

posted @ Saturday, December 02, 2006 1:33 AM | Feedback (0)

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

posted @ Wednesday, November 22, 2006 9:50 PM | Feedback (4)

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

posted @ Monday, November 20, 2006 6:33 PM | Feedback (12)

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.

posted @ Saturday, November 18, 2006 2:11 PM | Feedback (0)

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.

posted @ Saturday, November 11, 2006 11:49 AM | Feedback (5)

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

posted @ Wednesday, November 08, 2006 8:04 PM | Feedback (21)

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

posted @ Tuesday, November 07, 2006 4:52 PM | Feedback (6)

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!

posted @ Saturday, November 04, 2006 5:10 PM | Feedback (2)

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

posted @ Saturday, November 04, 2006 5:02 PM | Feedback (2)

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

posted @ Thursday, November 02, 2006 6:34 AM | Feedback (11)

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

posted @ Wednesday, November 01, 2006 10:29 PM | Feedback (15)

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

posted @ Tuesday, October 31, 2006 6:03 PM | Feedback (1)

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), ...

posted @ Monday, October 30, 2006 7:11 AM | Feedback (6)

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

posted @ Monday, October 30, 2006 12:28 AM | Feedback (0)

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

posted @ Sunday, October 29, 2006 11:42 PM | Feedback (3)

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

posted @ Saturday, October 28, 2006 1:14 AM | Feedback (0)

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

posted @ Friday, October 27, 2006 8:09 PM | Feedback (3)

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

posted @ Monday, October 23, 2006 10:47 PM | Feedback (7)

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

posted @ Thursday, October 19, 2006 5:41 PM | Feedback (0)

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

posted @ Wednesday, October 18, 2006 7:48 PM | Feedback (2)

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

posted @ Wednesday, October 18, 2006 7:24 PM | Feedback (3)

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.

posted @ Tuesday, October 17, 2006 9:22 PM | Feedback (5)

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

posted @ Monday, October 16, 2006 8:15 PM | Feedback (0)

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

posted @ Sunday, October 15, 2006 11:06 PM | Feedback (1)

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

posted @ Saturday, October 14, 2006 11:47 PM | Feedback (5)

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

posted @ Saturday, October 14, 2006 7:18 PM | Feedback (14)

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

posted @ Saturday, October 14, 2006 10:34 AM | Feedback (1)

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

posted @ Thursday, October 12, 2006 12:50 AM | Feedback (3)

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.

posted @ Monday, October 09, 2006 3:29 PM | Feedback (0)

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

posted @ Saturday, October 07, 2006 6:26 PM | Feedback (4)

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

posted @ Saturday, October 07, 2006 5:55 PM | Feedback (0)

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

posted @ Saturday, October 07, 2006 4:52 PM | Feedback (3)

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

posted @ Thursday, October 05, 2006 11:20 PM | Feedback (0)

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

posted @ Wednesday, October 04, 2006 11:23 PM | Feedback (2)

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

posted @ Wednesday, October 04, 2006 11:19 PM | Feedback (0)

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

posted @ Tuesday, October 03, 2006 6:24 AM | Feedback (2)

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

posted @ Sunday, October 01, 2006 2:06 PM | Feedback (5)

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.

posted @ Sunday, October 01, 2006 12:18 PM | Feedback (0)

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?

posted @ Sunday, October 01, 2006 9:58 AM | Feedback (1)

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

posted @ Saturday, September 30, 2006 11:58 PM | Feedback (2)

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

posted @ Saturday, September 30, 2006 11:30 PM | Feedback (0)

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

posted @ Friday, September 29, 2006 3:18 PM | Feedback (5)

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

posted @ Monday, September 25, 2006 12:32 PM | Feedback (11)

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

posted @ Monday, September 18, 2006 11:52 PM | Feedback (5)

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

posted @ Monday, September 18, 2006 9:18 PM | Feedback (4)

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

posted @ Saturday, September 16, 2006 2:29 AM | Feedback (6)

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

posted @ Thursday, September 07, 2006 6:09 PM | Feedback (2)

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

posted @ Sunday, September 03, 2006 3:24 PM | Feedback (3)

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

posted @ Thursday, August 31, 2006 4:40 PM | Feedback (6)

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

posted @ Monday, August 21, 2006 9:09 PM | Feedback (1)

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

posted @ Monday, August 21, 2006 6:40 PM | Feedback (0)

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

posted @ Wednesday, August 09, 2006 10:17 PM | Feedback (0)

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() { ...

posted @ Wednesday, August 09, 2006 8:38 AM | Feedback (3)

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

posted @ Sunday, August 06, 2006 3:27 AM | Feedback (0)

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

posted @ Friday, August 04, 2006 8:30 PM | Feedback (2)

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

posted @ Friday, August 04, 2006 6:24 PM | Feedback (0)

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

posted @ Friday, August 04, 2006 9:54 AM | Feedback (0)

NHibernate Query Generator Source Avialable

You can get it here, patches are welcome :-)

posted @ Wednesday, August 02, 2006 7:08 AM | Feedback (0)

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

posted @ Monday, July 31, 2006 8:34 PM | Feedback (10)

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.

posted @ Monday, July 24, 2006 8:27 PM | Feedback (2)

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

posted @ Monday, July 24, 2006 8:20 PM | Feedback (0)

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

posted @ Monday, July 24, 2006 12:04 PM | Feedback (7)

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

posted @ Friday, July 14, 2006 10:29 PM | Feedback (0)

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

posted @ Friday, July 07, 2006 12:38 PM | Feedback (4)

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

posted @ Sunday, July 02, 2006 5:47 AM | Feedback (2)

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

posted @ Saturday, June 24, 2006 12:55 AM | Feedback (3)

NHibernate Commiter

I just wanted to announce that I have been choosen as a commiter in NHibernate :-D

posted @ Tuesday, June 13, 2006 5:39 AM | Feedback (7)

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

posted @ Monday, June 05, 2006 6:44 PM | Feedback (0)

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

posted @ Friday, May 26, 2006 11:50 AM | Feedback (5)

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

posted @ Monday, May 22, 2006 10:11 PM | Feedback (2)

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.

posted @ Monday, May 15, 2006 11:57 PM | Feedback (4)

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

posted @ Sunday, May 14, 2006 11:02 PM | Feedback (6)

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

posted @ Friday, May 12, 2006 11:05 PM | Feedback (1)

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

posted @ Friday, May 12, 2006 4:44 PM | Feedback (0)

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.

posted @ Monday, May 01, 2006 5:15 AM | Feedback (2)

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

posted @ Sunday, April 30, 2006 10:10 PM | Feedback (4)

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.

posted @ Sunday, April 30, 2006 7:25 PM | Feedback (1)

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

posted @ Monday, April 24, 2006 10:38 PM | Feedback (3)

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

posted @ Monday, April 24, 2006 8:44 PM | Feedback (0)

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

posted @ Tuesday, April 18, 2006 10:01 AM | Feedback (4)

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

posted @ Friday, April 14, 2006 7:45 PM | Feedback (2)

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

posted @ Friday, April 14, 2006 9:46 AM | Feedback (4)

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

posted @ Thursday, April 13, 2006 12:15 PM | Feedback (6)

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

posted @ Monday, April 10, 2006 11:52 PM | Feedback (0)

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

posted @ Wednesday, March 29, 2006 9:11 PM | Feedback (0)

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

posted @ Saturday, March 25, 2006 6:00 AM | Feedback (3)

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

posted @ Saturday, December 24, 2005 4:22 PM | Feedback (0)

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.

posted @ Friday, December 23, 2005 11:34 AM | Feedback (0)

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

posted @ Monday, December 19, 2005 11:30 PM | Feedback (0)

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!

posted @ Wednesday, October 12, 2005 1:28 AM | Feedback (0)

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

posted @ Friday, October 07, 2005 11:54 PM | Feedback (0)

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

posted @ Friday, October 07, 2005 11:43 PM | Feedback (0)

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.

posted @ Friday, October 07, 2005 3:40 PM | Feedback (0)

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 :-)

posted @ Saturday, October 01, 2005 1:26 PM | Feedback (0)

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

posted @ Saturday, October 01, 2005 1:21 AM | Feedback (1)

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

posted @ Friday, September 30, 2005 9:15 PM | Feedback (0)

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

posted @ Friday, September 30, 2005 4:40 PM | Feedback (2)