NHibernate or FluentNHibernate or ActiveRecord? - nhibernate

I am in a stage of mapping my CSharp classes into database tables. I have decided to use NHibernate as my ORM tool after comparing with other tools. I have never done a real project with NHibernate before and now am considering alternatives for the mapping,
ActiveRecord: according to the project's web site, using ActiveRecord can boost productivity dramatically. However, I do not like the idea of adding attributes to my CSharp classes. After all, my class should NOT have any knowledge of database relationships. By using ActiveRecord will bind my nicely separated classes to ActiveRecord, and give me hard time if I ever want to switch underline DAO Layer implementation in the future.
FluentNHibernate: FluentNhibernate was my first attempt when starting mapping. But I also have a few issues with this approach. 1) I don't like my mapping strategies compiled as binary files. I would like to be able to change mapping by modifying xml files. 2) The maturity of FluentNHibernate. NHibernate has been around for a long time, and has LOTS of users, so I am quite comfortable with its maturity. On the contrast, FluentNhibernate is relatively young and not been tested by as many users. Even though I could dive into the source to fix whatever issue comes up, I am not comfortable with my skills to touch the low level implementation. 3) Availability of documentation for FluentNHibernate is much than that of NHibernate. I would like to have a place to go when I hit a hard wall.
NHibernate: Currently, I am using naked Nhibernate xml to do the mapping. To be honest, working with XML gives me massive headaches. Literally, I have to keep myself from the impulsion of just throwing away the .hbm.xml files and grab ActiveRecord or FluentNHibernate several times a day.
So, here is my dilemma: Should I go with my heart of "Just get this damn thing done!"; Or, should I follow the "Good practice guideline" to suffer the pain now and get relatively easy time later on?
Any comments?

Please note that any classes related to an ORM should not necessary be treated as "business object" classes or exposed to your UI. They should be considered part of your data layer. This pattern is not really unique to ActiveRecord. In general, you want your business layer to know as little as possible regarding the fact that there is an ORM beneath it, and you don't want your UI to know about your data layer. You also want to consider DTOs.
Fluent NHibernate solves the problem of having weakly typed XML which can be error prone to refactor.
While there can be downsides of adopting something like ActiveRecord, it seems like an appropriate solution in your case.
The best reason to use .hbm.xml files is if you are going to code generate them from your database (using something like CodeSmith). Hand coding the .hbm.xml files is rarely the best option.

Related

Where is the api reference for nhibernate?

I may be going mental, but I can not find any api reference material for nhibernate. I've found plenty of manuals, tutorials, ebooks etc but no api reference. I saw the chm file on the nhibernate sourceforge page, but it doesn't seem to work on any of my PCs (different OSes)
Can someone please point me in the right direction?
I just found this one:
http://web.archive.org/web/20141001063046/http://elliottjorgensen.com/nhibernate-api-ref/index.html
It doesn't seem to be official, but at least it looks like an API reference... unlike the official reference, which mostly describes concepts and mappings without any information about classes and members.
If you're on Windows, get ILSpy and point it at NHibernate.dll. It's not quite the same as real API documentation, but it's not half bad.
There is no class references publicly available on Internet as far as I know. You may build it from the source. Clone them, build the NHibernate.sln solution, then go into doc folder, ensure you have prerequisites indicated in reference\readme.txt file, and run nant doc. This will generate the class reference in the build folder.
Otherwise the most commonly used API are not wide, and most of them are xml documented with intellisens working in Visual Studio. The reference documentation has the advantage of giving more context, probably helping avoiding pitfalls like believing ISession.Update is to be used for updating entities (this is wrong, you do not need it unless you use detached entities, or entities coming from another session).
Official documentation reference is on https://nhibernate.info.
Sub-links:
Global documentation list
Reference (What I mostly use, especially following sub parts.)
Configuration
Mapping - basic / entities. (Add mapping xsd definition file in any or your solution folders for letting VS know it and give you intellisens in your hbm mappings.)
Mapping - collections
Querying - general. Do not miss the named queries feature in The IQuery interface.
Querying APIs:
HQL. I mostly use HQL with named queries, in mappings, for queries not dynamically built. They get parsed and validated when building session factory, which normally occurs at application startup, so it is almost as good as compile time validation. Checks log4net logs to get detailed reasons of named query parsing failures.
Criteria API. I view it as the historical way of dynamically building queries in code, to be preferred over constructing HQL strings.
QueryOver API. Based on Criteia API, with lambda expression support for having compile time validation of queried entities namings. Should be preferred over Criteria API in my opinion.
Linq API. Great for dynamically built queries. Bear in mind that its implementation translates your queries to HQL. With complex queries, it may generate unsupported HQL constructs. Having knowledge of HQL capabilities allows a better understanding of how to write a supported Linq query for complex cases. (By example, for a complex order by, better use an explicit linq sub-query in the OrderBy rather than using a collection mapped on your queried entity.)
Native SQL. Well, quite self-explanatory. To be used by example when you need some SQL special feature not available through other querying APIs (SQL server full-text, select for xml, ...), and that you do not wish to extend those other APIs. You may also call stored procedures. When using native SQL, I favor SQL named queries.
Modifying data, from Updating objects to Flush, and Exception handling.
Performances.
Batch fetching. About this, you may read my post here for a detailed explanation of why lazy loading can be very efficient with NHibernate, thanks to batch fetching. This single feature will always cause me to prefer NHibernate over Entity Framework, till it ceases being lacking in EF.
Second level cache. Another great NHibernate feature, lacking native support in EF. Beware, you must use transactions for leveraging this. It allows NHibernate to automatically evict cached entries for you as you change data through your application process. Without transactions, NHibernate will disable the second level cache as soon as you start changing data, for avoiding letting the cache yield you stale data.
Interceptors. This is one way among many allowing to customize NHibernate inner working. NHibernate is very strong at allowing you to extend it. You may also add your own HQL extensions as here, your own linq2NH extension as here (all are answers from me). And there are other ways, see this list for linq2NH extensibility solutions.
Moreover, a class reference will very likely be near the Hibernate one. There is so many internals APIs supporting its implementation that is not much usable.
Why are such API not hidden (internal, private, ...)? Not hiding them is required for allowing the great extensibility capabilities of NHibernate. Those capabilities are a must have in my opinion. In contrast, it is so hard to fix some other .Net project shortcomings, due to lacks of extensibility they suffer. (MVC FileResult and the TweakDispositionAsInline I had to use instead of just being able of overriding some method, or try extend linq-to-entities, see this.)
there is a good book that covers a lot, and there is the html documentation on the site (which also comes as a book)
(the book would be manning - nHibernate in Action - a little outdated, but a good start)
Here is the link to the online reference

Help me choose between linq to sql and nhibernate based on the following

Struggling between choosing linq2sql and nhibernate.
Let me give you some insight in the application in point form:
this is a asp.net mvc application
it will have lots of tables, maybe 50-60 (sql server 2008)
i would want all the basic crud logic done for me (which I think nhiberate + repository pattern can give me)
i don't have too complicated mappings, my tables will look something like:
User(userID, username)
UserProfile(userID, ...)
Content(contentID, title, body, date)
Content_User(contentID, userID)
So in general, I will have a PK table, then lots of other tables that reference that PK (i.e. FK tables).
I will also have lots of mapping tables, that will contain PK, FK pairs.
Entity wise, I want User.cs, UserProfile.cs and then a way to load each object.
I am not looking for a User class that has a UserProfile property, and a Content Collection property (there will be maybe 10-20 tables that will related to the user, I just like to keep things linear if that makes sense).
The one thing that makes me learn towards nhibernate is: cross db potential, and the repository pattern that will give me basic db operations accross all my main tables almost instantly!
Since you seem to have a quite straight forward mapping from class to table in mind Linq to SQL should do the trick, without any difficulties. That would let you get started very quickly, without the initial work of mapping the domain manually to the database.
An alternative could be using NHibernate + Fluent NHibernate and its AutoMapping feature, but keep in mind that the Fluent NHibernate AutoMapping is still quite young.
I'm not quite sure I understand what you want your entities to look like, but with Linq to SQL you will get a big generated mess, which you then could extend by using partial classes. NHibernate lets you design you classes however you want and doesn't generate anything for you out of the box. You could kind of use POCO classes with Linq to SQL but that would take away all the benefits of using Linq to SQL rather than NHibernate.
Concerning the repository pattern, and the use of a generic repository, that can be done quite nicely with Linq to SQL as well, and not only with NHibernate. In my opinion that is one of the nice things about Linq to SQL.
If you probably will need support for other databases than SQL Server, NHibernate is the only choice. However, if it probably won't be an issue I would recommend not using that as the primary factor when choosing. The other factors will probably influence your project more.
Conclusion:
All in all, I would recomment Linq to SQL, in this case, since it would let you get started quickly and is sufficient for your needs. The precondition for that is that you don't have a problem with the thought of having generated, messy code in your domain, and that you are quite sure there will not be any need to support other databases in the future. Otherwise I would recommend NHibernate, since it is truly an awesome ORM.
linq2sql really wants you to work with 1 table per class mapping. So if you have a UserMaster and a UserDetail table, you are looking at two objects when using default linq object generation. You can get around that by mapping linq entities to business entities (see Rob Conery's storefront screencasts), but then you are back to writing object mapping code or using something like Automapper.
If you want to be able to split your classes across multiple tables, then I'd say go with NHibernate. If not, then linq has a lower learning curve.
The only way I'd ever use nHibernate in through Castle Project's ActiveRecord library. Otherwise, nHibernate becomes its own little infrastructure project. Check out some questions in the nHibernate tag to see what I'm talking about.
The only thing I might change about AR is to return results of SELECT operations as List instead of T[]. Of course, with the source code in C# I can do that if I want.
With ActiveRecord, the mapping information is saved in attributes you decorate your classes with. It's genius and I am a huge proponent of the pattern and this particular library.

What is so great about ORM?

So I'm having a head against the wall moment and hoping somebody can come help either remove the wall or stop my head from moving!!
Over the last 3/4 weeks I've been investigating ORM's in readyness for a new project. The ORM must map to an existing, large and ageing SQL database.
So I tried Subsonic. I really liked v2 and v3 after modding to work nicely with VB and named schemas in SQL was running OK. However, its lack of flexibility of having separate entity properties names vs column names had me pulling my hair out (sorry Rob).
I tried Entity Framework but I found like others it lacking in certain areas.
So I bit the bullet and tried nHibernate but after a week or so getting it working how I liked (with help from Codesmith to generate classes/hbms for me) I'm frustrated with the time it takes to startup (build a config object), despite trying a number of tricks to reduce this time.
I'm essentially after building a DAL class that I can share between apps and websites. Am I barking up the wrong tree? For a legacy project with 100s of tables should I go back to ado.net and use DTOs? Aarrgh!
Sorry for the ranty style of question. I don't have much hair left and I'd like to keep what I have!!
Thanks in advance, Ed
PS. I should add that I know SQL very well and not scared of getting my hands dirty to write fast queries. If anything I don't need to be hid from SQL
ORM let's you:
To map table rows to objects, that are the the workable pieces of object oriented programming.
To automatically navigate through object relationships
To easily add, edit and remove table rows
To query the database in a more intuitive way as you don't have to think of joins (this one will depend on the ORM and the query method)
To transparently handle L1 and L2 cache.
All of the above would have to be handled by hand if you werent using ORM.
PS: I agree to Dmitry as to the startup time of NHibernate (see question comments). Besides, did you try Fluent NHibernate? Fluent NHibernate is impressively easy. I couldn't believe my eyes when I first mapped a database. It's even easier than proprietary ORMs like DevExpress XPO.
The biggest benefit of an ORM tool is that it will help you layer your application correctly. Most project nowadays use a Data Layer to connect to the database. You start from the ORM tool to produce classes that correspond to your database objects. Then you define an interface using these methods. All persistence code uses the methods of this interface. This way the business logic layer is only coupled to this higher-layer interface and needs to know nothing about the database. In fact there should be no dependency on ADO.NET or even NHibernate.
Another advantage of ORM tools is that you de-couple your application from the database server. You could change the db engine and still use the same code. Also there isn't only the complexity of the SQL that the ORM hides from you. It can also help you with transactions logic and connection pooling.
I'd say that for new projects an ORM tool is a necessity. For legacy projects it isn't so much beneficial, unless of course you have the time/money to start from scratch.
In my experience, most ORMs end up being way more complex than SQL. Which defeats the entire purpose of using them.
One solution I'm enthusiastic about is LINQ2SQL. It excels as a thin layer about stored procedures or views. It's really easy to use and doesn't try to hide SQL.
There are basically two questions here:
What's great about ORMs? There are similar questions on Stackoverflow. See:
What are the advantages of using an ORM?
Is everyone here jumping on the ORM band wagon?
How can I improve NHibernate startup time? See:
http://ayende.com/Blog/archive/2007/10/26/Real-World-NHibernate-Reducing-startup-times-for-large-amount-of.aspx
http://nhforge.org/blogs/nhibernate/archive/2009/03/13/an-improvement-on-sessionfactory-initialization.aspx

Would you use NHibernate for a project with a legacy database, which is partly out of your control?

For me the answer is currently: No, I would use iBatis, because NHibernate is a pain, when the database model and the object model are not in synch. If I don't have full control over the database I end up with a lot of work.
Why do I ask?
Well, first of all: I never used NHibernate. I just know it from the surface. I have read about the advantages of iBatis for legacy databases.
Second: Recently I had a discussion with someone who worked with Hibernate (jep, without 'N' before Hibernate). He told me that the ORM frameworks are now pretty advanced and advocated Hibernate. Since I was not interested in NHibernate, I didn't keep track of the recent developments.
Maybe I its time to rethink my answer, or not?
iBatis is certainly easy to map objects to legacy database systems.
More recently NHibernate 1.2 and 2.0 have a feature set that may make you rethink iBatis.
NHibernate works with composite keys, which can occur frequently in older databases, they aren't always pleasant to work with but support is there for this.
NHibernate can utilise Stored Procedures for CRUD operations on entities, also database views.
Collections can be custom stored procedures or SQL queries. Collections can use the property-ref attribute when the Foreign Key relationship doesn't map directly to the Primary Key on the other side.
Some of these features may take away from the performance/power of nhibernate, ie Lazy Loading with property-ref doesn't work (at all?), but is most cases there are reasons for this.
Other points: (which aren't really related to your legacy database but still can help decide on a technology choice)
The Nhibernate community appears much richer than the iBatis. I'm on both lists and the volume of support for NHibernate is quite large compared to the iBatis group. So support should be easier.
Also there is a growing amount of contrib/3rd party tools for NHibernate. Things like The NHibernate Profiler, the Nhibernate Query Analyzer, NHibernate Contrib, Fluent NHibernate to name a few.
Perhaps you can expand on what advantages you believe iBatis currently has. NHibernate has certainly been quite active recently and has gained many new features, a lot of which do assist in legacy/hard to modify schemas.
And to answer the question, yes we do use NHibernate with legacy databases that have awful relationships, composite keys, broken relationships. We still also have a small amount of code based on iBatis. We no longer write any more iBatis code though.
Yes, consider NHibernate. It's the gold standard for a reason. I have heard that iBATIS supports crazy mapping possibilities, but with NHibernate's IUserType you can map anything, even really strange columns.
#Ahmad, the entire point of ORM is to prevent a tight coupling between your objects and your schema. If you have this problem you're doing it wrong.
Also, with NHibernate there are plenty of options for custom queries, formula properties and stored procedures. HQL is extremely powerful and Criteria is flexible.
I think you'll be doing your clients a disservice if you don't at least spike NHibernate.
I've been using nHibernate in an existing application. I use it for all new development, I have no intention of porting the existing stuff over either there just isn't a compelling reason but for new stuff on the project it works great.
If you are going to port the code over then you should be able to change the database to match better with your domain model, without much impact (depending on how leaky your database is ie who access it). Changing the domain model would impact the application however.

When choosing an ORM, is LINQ to SQL or LINQ to Entities better than NHibernate?

I find I can do more with NHibernate, and even Castle than with the Linq to Entities, or linq to SQL.
Am I crazy?
No you're not crazy. nHibernate is a full OR Mapper, Linq to SQL and Linq to Entities don't implement everything you'd expect from an OR mapper and targeted at a slightly different group of developers.
But don't let that put you off linq though. Linq is still a pretty good idea.. Try Linq to nHibernate :-)
The big drawbacks to NHibernate, Castle, etc., is that they're not exactly light-weight (especially NHibernate.)
Linq to SQL is good for a light-weight, limited use ORM.
I've used both NHibernate and LINQ to SQL. From my point of view it depends on the project, if I need something quick, I would choose L2S, it's so simple to create the dbml mapping and start using it. If I'm developing a more highlevel enterprise solution I would go for the tried and trusted ORM - NHibernate, I find the logging & transaction features simple to use.
LINQ to SQL has a relatively short learning curve, NHibernate has a much steeper learning curve.
LINQ to SQL only supports SQL Server, so if you've an Oracle database then the decision is already made - NHibernate.
I'd recommend checking out http://www.summerofnhibernate.com/ for excellent screencasts on learning NHibernate.
One thing to bear in mind is that NHibernate can be an absolute pig to configure - especially since its based mainly on XML config files because of its roots as the original Hibernate.
Fluent NHibernate goes some way to making this less painful.
Linq certainly though fits in with the general 'way' in which .NET works.
Blockquote Linq certainly though fits in with the general 'way' in which .NET works
Yikes, this kind of sentiment scares me. The RAD stuff built into .net is NOT how dot net works, it's just a tool set for getting prototypes up. .NET allows us to do full DDD applications, w/ high levels of cohesion, seperations of concerns, and allows us to write decoupled code, despite all the attemps ms makes to couple things. I would strongly disagree that .net likes to be coupled, certian tools like to be coupled, i'll include linq to sql in this fray. linq to sql destroys the idea of having a seperate domain model. I cringe at the thought of using my database schema as the underlying model objects. Proper ORM tools should allow us to model our domain first, then link our relational database to these models. NOT the other way around.
I have not tried the Entity Framework, but I definitely would recommend NHibernate over Linq to SQL; The biggest reason I can give is just the control. Linq to SQL likes to have a lot more control over everything, loading the object and maintaining all kinds of tracking information about the object. If you serialize/deserialize, the tracking information can be lost and strange things can happen when saving it again. NHibernate works more as a repository should - You hand it whatever object you want (that you have configured it to understand, of course), and it puts it away in the database, regardless of what you've done with it.