Try fast search NHibernate

08 April 2011

NHibernate 3.2: (part 2) mapping by code

GallettoAllaDiavola

In the first post about the new mapping-by-code feature you saw only the very first presentation.

I’ll will try to write more posts about this new feature and all its secrets even if you can learn more using ConfORM.

As in ConfORM even the NHibernate’s mapping-by-code is smarter than XML mapping and may help you in many cases. Well… it is not so smart as ConfORM but smart enough to prevent some common errors.

It’s beginner proof

Let me show you a simple case:

private class Person
{
    public int Id { get; set; }
    public ICollection<Address> Addresses { get; set; }
}

private class Address
{
    public Person Owner { get; set; }
    public string Street { get; set; }
    public Number Number { get; set; }
}

private class Number
{
    public Address OwnerAddress { get; set; }
    public int Block { get; set; }
}

An entity with a collection of components which has a nested component. The beginner may intent this mapping:

mapper.Class<Person>(cm =>
{
    cm.Id(x => x.Id);
    cm.Bag(x => x.Addresses, cp => { }, cr => cr.Component(ce =>
    {
        ce.ManyToOne(x => x.Owner);
        ce.Property(x => x.Street);
        ce.Component(x => x.Number, y =>
        {
            y.Component(x => x.OwnerAddress, map => { });
            y.Property(x => x.Block);
        });
    }));
});

hmmmm… a cyclic mapping of the nested component on OwnerAdress property ? Not for sure!! NHibernate knows how create the correct mapping Winking smile.

It’s even conformist

In these years I saw people writing mappings by-code but class-by-class as in XML… a very conformist attitude. Well… if you feel conformist don’t worry NHibernate 3.2 can be conformist too.

public class MyClass
{
    public virtual int Id { get; set; }
    public virtual string Something { get; set; }
}

public class MyClassMap: ClassMapping<MyClass>
{
    public MyClassMap()
    {
        Id(x => x.Id, map =>
        {
            map.Column("MyClassId");
            map.Generator(Generators.HighLow, gmap => gmap.Params(new { max_low = 100 }));
        });
        Property(x => x.Something, map => map.Length(150));
    }
}

Then you can add it to the ModelMapper in this way:

mapper.AddMappings(typeof(AnyMappingClass).Assembly.GetTypes());

NHibernate 3.2 too sexy by far!!!

25 comments:

  1. Hi There!
    Does it support auto-mapping same as fluent NH?

    ReplyDelete
  2. Can you explain what mean "auto-mapping" for you ?
    If it is too large please do it somewhere else, then put a link here.
    Thanks.

    ReplyDelete
  3. Hi,
    I think you are merging fluent NHibernate's capabilities (or something too close) and that's so good. It can eliminate that external dependency when NH 3.2 comes out.
    But FHN has another feature which is called auto mapping. by enabling that, it can scan your classes and create that manual "ClassMapping" definitions behind the scene automatically. so you don't need to write that "ClassMapping" classes:
    http://wiki.fluentnhibernate.org/Auto_mapping

    ReplyDelete
  4. Man!! you have to read something about ConfORM
    Only to start
    http://fabiomaulo.blogspot.com/2010/02/conform-nhibernate-un-mapping.html

    ReplyDelete
  5. I have no idea why you didn't just leverage FNH (at least the API which seems a lot nicer than this and then work on the internals) instead of reinventing the wheel.

    On your previous blog post you say 'Fluent NHibernate it not so sexy for me'.. Frankly the API you have come up with is rather ugly compared to the Fluent NHibernate api. Perhaps you should get the opinion of some other NHibernate developers before this becomes the 'official' nhibernate API.

    ReplyDelete
  6. It does seem wasteful to have 2 different mapping schemes in FNH and now this. I think it is an oversight to not merge FNH in.

    Have you any advice for legacy NH projects with lots of .hbm.xml files that want to use the new functionality.

    ReplyDelete
  7. Where can I vote up for excluding this feature from nh core?

    ReplyDelete
  8. What with Composite IDs? It will be possible define them in that way?

    ReplyDelete
  9. As usual. Foo people with stupid questions. My next post will be the last of the series then I will response only in the forum.

    ReplyDelete
  10. The thinking of FNH team leader
    http://twitter.com/#!/jagregory/status/54471549733965824

    ReplyDelete
  11. I love it !! much much better than the Fluent NHibernate DSL.

    And also it use the same *oficial* nomenclature of NHibernate that is in the reference documentation and so on.

    Keep the good work! and ignore the other crap comments.

    ReplyDelete
  12. very nice! and My post:http://bit.ly/h6fsCi

    ReplyDelete
  13. Fabio, this is great stuff! It is true that alot of users are now familiar with Fluent, but that still sits on top of the xml mappings. It is really great that you transfer the confORM ideas into NHibernate, so that we can finally write mappings directly into the core. Saving xml serialization during testing and debugging :)

    Question:
    - Can we use *.hbm.xml, fluent and this all intertwined?

    ReplyDelete
  14. @Melle
    For sure you can use XML, by-code and ConfORM altogether.
    With FNH too, you have to make some trick exposing the Conf and then doing some other trick to remove some mapping.

    ReplyDelete
  15. @milley
    in ConfORM no but in NH yes, somebody have to implement it... perhaps I'll... with 2 or 3 JD-N7 perhaps I can.

    ReplyDelete
  16. Thanks Fabio for good news, because this is the thing that stopped me in switch from FNH to ConfORM, and I'm really happy hear you thinking about implementing this in NH loqacious api :)

    ReplyDelete
  17. Great work, Fabio. Can't wait to use it in my next project :-)
    Personally I've never loved FNH and I've just used it to build the skeleton of my HBL.XML files which I then refined and used in my solutions.
    Forget about those silly comments. The IT world is full of sheeps. They've been told that FNH is cool and easy.

    ReplyDelete
  18. Good work Fabio!

    For me it was a good decision to not merge FNH. The larges problem of them is still that there naming and structure dose not follow the xml configuration.

    ReplyDelete
  19. This is a nice article..
    Its easy to understand ..
    And this article is using to learn something about it..

    c#, dot.net, php tutorial, Ms sql server

    Thanks a lot..!
    ri80

    ReplyDelete
  20. Really dont understand why you want to spend time on this when there is already Fluent NHibernate.

    I Think the time would be much better spent on the Linq Provider and Performance optimizations.

    Also James Gregory and others have spent a whole lot of time creating and supporting Fluent NHibernate and now it seems like you are trying to eliminate all their hard work and great contributions, instead of working together.

    ReplyDelete
  21. Another post about the subject
    http://moh-abed.com/2011/08/14/nhibernate-3-2-mapping-entities-and-value-objects-by-code/

    ReplyDelete
  22. @Mohammed
    About flexibility: the lambda based mapping is more flexible and more extensible than a fluent API.
    It is so true that you can use the impl. in NH to create the FNH API... try to do the inverse.

    ReplyDelete
  23. @Fabio you got a point about the flexibility of lambda expression although is is more complicated, and you are right you can build the fluent api over it.

    ReplyDelete
  24. @Fabio
    I have question regarding your sexy mapping implementation :-).

    How to implement .ChildWhere() mapping with many-to-many relation in NH 3.2?

    For more details see here: http://stackoverflow.com/questions/8732692/how-to-implement-childwhere-mapping-with-many-to-many-relation-in-nh-3-2

    This feature doesn't implemented yet? Or am I doing something wrong...

    Need your help.

    ReplyDelete