FluentNHibernate or port to NHibernate mapping by code - nhibernate

I have several projects using NH and FNH to generate the mappings (some Fluent some Automapped). There are still some bugs and missing features i need, but it seems that FNH could die because of mapping-by-code integrated into NHibernate.
Question: Contribute to FNH or to migrate the mappings to mapping-by-code or confORM and fixing problems/implementing features there?

At our office, we have been using NHibernate for 3 years now. We've been thinking about making a move to Fluent Nhibernate but never made the move. Using hbm.xml files was still the easiest to debug/alter. Two common problems of those xml files are that they are all validated during the creating of the sessionfactory and they are not refactor-safe.
Due to a bug I had to update a newer release of NHibernate (we were using NHib 2.1.2GA) and when I implemented 3.2GA we also were handed the ability to use loquacious mappings (mapping by code). I decided to use Loquacious over Fluent because I don't have a dependency to another project (Fluent) and the fact that NHibernate won't be shipped if mapping by code is broken.
Be aware though, that Loquacious mapping isn't complete either. While I was mapping everything by code, I found out basic stuff like property-ref wasn't always implemented. Thus even though it's shipped, it's not 100% complete. And while this will not come as a shocker, it has bugs. yes. really. ;-)
for more info on (reported) bugs, check out the NHibernate bug database: https://nhibernate.jira.com/browse/NH
Hope this helps.
Regards, Ted

thx to #TedOnTheNet i will continue to use and contribute to FNH, because it will take a while until mapping-by-code reaches FNH in some areas
Automapping
Fluent API tells a lot better which possibilities there are
far more verbose mappings
.Database(SQLiteConfiguration.Standard.InMemory()) is still easier to figure out than
.DataBaseIntegration(db =>
{
db.ConnectionString = ???;
db.Dialect<SQLiteDialect>();
db.Driver<???>();
});
and some features:
CompositeId and Table per Subclass
default values for legacy columns
property refs
Update: some features from hbm.xml (and FluentMapping) will not be possible at all with mapping by code:
default values for legacy columns: database column to constant value without the need for a property in the entity class with mapping by code
query only properties/collections: http://ayende.com/blog/4054/nhibernate-query-only-properties

NH 3.2 does not have anything remotely equivalent to FNH's Automapping, as far as I can tell. (For me, that would be a dealbreaker).
Edit
The FNH Automapper can deal with most of the common patterns in an object model, such as inheritance, one-to-many relationships, self-referencing, etc - without requiring any help from the programmer. So far, pure NH has not achieved this level of automation.
Also, James Gregory has publicly stated that he will continue to develop FNH, at least in the near term. (Think I saw this on the FNH Google group a few months back, but I'm not sure exactly where).

Related

Getting Started with Fluent NHibernate

I'm trying to get into using Fluent NHibernate, and I have a couple questions. I'm finding the documentation to be lacking.
I understand that Fluent NHibernate / NHibernate allows you to auto-generate a database schema. Do people usually only do this for Test/Dev databases? Or is that OK to do for a production database? If it's ok for production, how do you make sure that you're not blowing away production data every time you run your app?
Once the database schema is already created, and you have production data, when new tables/columns/etc. need to be added to the Test and/or Production database, do people allow NHibernate to do this, or should this be done manually?
Is there any REALLY GOOD documentation on Fluent NHibernate? (Please don't point me to the wiki because in following along with the "Your first project" code building it myself, I was getting run-time errors because they forget to tell you to add a reference. Not cool.)
Thanks,
Andy
I've been using Fluent NHibernate Automapping for a few months now. I'm by no means an expert, but can take a stab at your questions...
FNH Automapping does indeed create DB schemas from POCO classes, including lists of other objects (this was the reason I chose NHibernate in the first place).
When you change schemas, you have to rerun the automapping, which does drop the whole database, unfortunately. In my case, it's not a big problem because I'm importing existing binary data files, so I just have to re-import my data every time the schema changes. I've read that there's some data migration support available with NHibernate, but have no experience with this. (BTW, Subsonic will do data migration, but it's automapping functionality is far more rudimentary - at least it was when I evaluated it a few months ago)
FNH documentation is one of my pet peeves - they have not even added Intellisense help on the method names, etc. (But they get really huffy when you point that out - ask me how I know!) I've made a couple of edits to the wiki when I could, but there's so much more that could be done there. The best approach is to start with a working example (i.e.
this one from Nikola Malovic, and post questions to the support form if (when!) you run into trouble. In general, I've found the FNH community pretty helpful, and have been able to work through all my difficulties. They've also fixed a couple of bugs I've found.
Overall, using FNH has been a huge win for my project - highly recommended!
I don't use Fluent, but I can help with classic NHibernate.
yes, the creation of the schema is very recommendable for production use (Schema Export). When you do this is up to you. For instance, you could create the database by an installer. You shouldn't drop existing databases, but this is a decision of you application.
I don't understand this question. Do you mean you need to upgrade an existing database to a new database schema? This is unfortunately something you need to implement yourself. NH can't do much about this, because it is very specific to you data and the changes you made. There is also a Schema Update or something like this, which is not recommended for production use.
I don't use Fluent, so I can't help here.

Tool to generate Fluent NHibernate mappings

I am trying to integrate NHibernate into an existing application with several hundred tables. Due to the fact that there apparently wasn't a strict adherence to conventions, I am unable to use Automap. As a result, I'm going to use Fluent to manually map over all of the associations.
Rather than doing it by hand, I'm hoping that there is a tool in existance that can either run through my solution or the database and stub out mappings.
Does anyone know of any project out there with this in mind?
Thanks!
I don't know of a tool that does it in Fluent, but there are plenty of options for doing it with the old hbm xml files. CodeSmith and MyGeneration are two that are recommended as a starting point for your classes and hbms.
LLBLGen Pro V3 will do exactly this, it can generate either tradition .hbm.xml or fluent mappings for your entire database.
Old question, maybe still relevant to some. If you are looking for an open source solution, try NHibernate Mapping Generator

Fluent Nhibernate and hbms

As an FNH user, do you find you sometimes need to supplement FNH with an hbm file? Any relatively common edge cases where you do, if so?
Cheers,
Berryl
If you need to use named queries you will need to use an hbm file and you would probably use a named query to call a stored procedure whether this be because you have legacy stored procs to call, possibly performance or in my most recent case, to do a full text search. More info on setting this up can be found here and here.
When a bug in Fluent NHibernate prohibits something. There are less bugs each release, but you might find some eventually (the most recent is the inability to map dictionaries when certain auto mapping conventions exist)
When you have a legacy system (mapped using hbms) for which you need to add new domain objects (mapped using fnh and/or automapping).
I'm using FNH Automapping on my (so far, one and only) NHibernate project.
At first, I had to write a couple of FNH overrides to work around bugs. But the bugs were quickly fixed by the FNH team, and I was able to eliminate the overrides completely.
Never had to deal with the HBM files, and I hope it stays that way!

Fluent NHibernate. Auto Mapping and Conventions

Im new to NHibernate, the configuration aspect of it has always seemed overly onerous to me. Yesterday, I came across the Auto Mapping features of Fluent NHibernate and was suitably impressed.
To educate myself, I set myself the challenge of attempting the 'Getting Started First Project' (http://wiki.fluentnhibernate.org/show/GettingStartedFirstProject) using AutoMappings and Conventions. I have to admit to not having much luck.
To summise my steps:
I made some minor changes to the database schema in the example, mainly to remove the underscores from the foreign keys (i.e. Product_id to ProductId) as this would bring it more inline with our database naming standards.
Q1) I tried to write a IHasManyConvention implementation using the ForeignKeyConvention as an example but the WithKeyColumn method doesnt seem to exist (I presume this is because I downloaded yesterdays build so subsequently the design has changed since the article was written). How do I rectify this?
I also made some minor changes to the Entities layer in the example as I thought this would make it easier, they were to rename StoresStockedIn to Stores (Product.cs) and Staff to Employees (Store.cs).
My code looks like this:
var cfg = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.ConnectionString(c => c
.Is(connectionString)))
.Mappings(m => m.AutoMappings.Add(
AutoPersistenceModel.MapEntitiesFromAssemblyOf<Store>()
.Where(t => t
.Namespace == "FluentNHibernateTesting.Entities")
.ConventionDiscovery.Setup(c => c.Add<ForeignKeyConvention>())
))
.BuildSessionFactory();
I then try and add the stores, products and employees to the database as per the getting started example. The exception I get happens on the Commit and is:
object references an unsaved transient instance - save the transient instance before flushing. Type: FluentNHibernateTesting.Entities.Employee, Entity: FluentNHibernateTesting.Entities.Employee
Q2) How do I resolve this problem? I understand (from my limited reading) that it has something to do with setting up the cascade elements of object relationships correctly but Im a bit stumped about how to go about this effectively using Auto Mapping.
Q3) Is there a target release date for the Fluent project? I (like I assume many others) feel this is an excellent initiative but am mindful of using it unless it is in a stable state.
Q4) Its mentioned in many of the blogs that they are working steadily towards parity of the features in Fluent with hbn.xml. Is there a list of these missing features somewhere in order to aid with the evaluation and usage of this tool?
Appreciate the help in advance.
I asked James Gregory the same questions in an email to him directly. He provided this excellent response.
'Hey Paul,
1) KeyColumnNames is what you're after.
2) You can do this one of 3 ways. Setup a IHasManyConvention to globally make all relationships cascade, use a ForTypesThatDeriveFrom call, or an automapping override.
3) We're in private testing of our 1.0 release now. Unsure whether we'll have a public beta or straight to release, but that should happen in the next few weeks.
4) It's very unlikely we'll ever be completely feature complete with NHibernate, we have no desire to be. Many of the NH features are extremely esoteric, and there is little benefit to us implementing them. As of 1.0 there will be very few features that we don't support that people use regularly. I can confidently say all common mapping scenarios are catered for, and if there's anything that isn't you can always drop back to hbm for that case.
To pre-empt any comments that our docs are out of date, documentation is going to be overhauled for 1.0 ;)
James'
Thanks James.
Is there a target release date for the
Fluent project? I (like I assume many
others) feel this is an excellent
initiative but am mindful of using it
unless it is in a stable state.
You should be able to get a working version of Fluent nHibernate from their SVN repository now. They also have compiled binaries.
There currently aren't any official releases of Fluent NHibernate. This is not a reflection of quality, but of our rapid rate of change. Our code-base is being updated daily , which makes putting out official releases a pointless endeavor until we achieve feature parity with NHibernate Core. Most of the regular features you use day-to-day are ready.
http://fluentnhibernate.org/downloads
The current issues are here:
http://code.google.com/p/fluent-nhibernate/issues/list
None of them appear to be deal-killers. I guess it depends on how much time you have to experiment.
object references an unsaved transient
instance - save the transient instance
before flushing. Type:
FluentNHibernateTesting.Entities.Employee,
Entity:
FluentNHibernateTesting.Entities.Employee
If you Google object references an unsaved transient instance, you will find several matches for this. Your best bet is to start going through these and troubleshooting. Anecdotally, from what I've read it sounds like the error message means exactly what it says, or there is a many-many or cascading relationship that is not getting updated.

NHibernate or FluentNHibernate or ActiveRecord?

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.