Breaking changes with NHibernate 4 upgrade
Asked Answered
D

3

5

I can see what's new and fixed in NHibernate 4.0

I would like to know if anyone has had issue with hbm mappings upgrading from NHibernate 3 to 4?

I fear that more focus is going on fluent mapping these days. I can test for the more obvious breaking changes but wanted to know if there were any subtle issues that anyone has come across in a production environment that may not be so obvious at first.

It looks like a major upgrade and you'd expect there to be the risk of regressions.

Disrepute answered 22/8, 2014 at 15:30 Comment(2)
A fair question, but a poll, nevertheless.Amalberga
A fair comment, I've articulated my concern more accurately. I like this on hold feature, it's my first encounter and it's much better than the old simply closed.Disrepute
P
3

I wouldn't worry too much about the hbm itself. FluentNHibernate "compiles" to XML which goes through the mapping layer. NHibernate's own mapping-by-code also uses parts of the same code as hbm files.

Anyway, the mapping code hasn't changed very much. Any regressions are more likely to be in other parts.

Premature answered 26/8, 2014 at 19:5 Comment(0)
W
9

FYI, I found a new error that is thrown. We use Mapping By Code, and we used to have an entity that had multiple Bag mappings with the Fetch type set to Join with NHibernate v 3.3.x. This is no longer allowed in version 4.0.x.

We received an error message of Cannot simultaneously fetch multiple bags., which makes sense with what is necessary behind the scenes but it should technically be considered a breaking change. NHibernate was not nice enough to tell us which mapping was causing the issue.

Wapiti answered 7/11, 2014 at 19:39 Comment(5)
good point, hit this as well but then realised it's a good deprecation. your queries are likely to be inefficient and bringing back a large table of data, consider using futures.Disrepute
Apparently, Set knows to do a separate query in the same batch, so there shouldn't be an issue with cartesian products like Bags can have.Wapiti
Also using Mapping by Code, I couldn't get an enum mapping to work correctly (using SQLite, if that matters). It works fine during save, but retrieval with Get doesn't work - It seems to be trying to convert the string "System.Byte[]" to the enum type, which of course won't work. Couldn't find a good reference anywhere, yet.Altorelievo
@jweyrich, I've had no trouble with enums. I have the ID property of a class mapped to the column, nothing else. Works fine. Create a question and send me the link and I'll see if I can help.Wapiti
With FluentNHibernate it works like a charm. Not so lucky without it. Anyway, I've switched to Fluent for now. Thanks for the support anyway.Altorelievo
A
6

We were experiencing the same issue with a rather large QueryOver - Cannot simultaneously fetch multiple bags, with Nhibernate 4 and FluentNhibernate mappings.

The solution was to, on our FluentMaps, to set AsSet() (according to our backing fields) which in the end solved the issue.

As per request in the comment, here is a small sample of our mappings before and after the exception:

This is a very simplified showcase of our classes which caused the Cannot simultaneously fetch multiple bags. The abstract Entity class belongs to the S#Arp lite architecture. Before the changes it looked something like this

public class OrderHeader : Entity
{
    public virtual IList<OrderItem> Items { get; set; }
}

public class OrderItem : Entity
{
    public virtual decimal Price {get; set;}
    public virtual string ItemNumber {get; set;}
    public virtual OrderHeader Header {get; set;}
}

public class OrderHeaderMap : ClassMap<OrderHeader>
{
    Id( e => e.Id).GeneratedBy.Native();
    HasMany(e => e.OrderItems).Inverse();
}

public class OrderItemMap : ClassMap<OrderItem>
{
    Id(e => e.Id).GeneratedBy.Native();
    References(e => e.Header).Not.Nullable();
}

As you can see the OrderHeader has an IList of items. Changing this to

public class OrderHeader : Entity
{
    public virtual ISet<OrderItem> Items { get; set; } // ISet here
}

public class OrderItem : Entity
{
    public virtual decimal Price {get; set;}
    public virtual string ItemNumber {get; set;}
    public virtual OrderHeader Header {get; set;}
}

public class OrderHeaderMap : ClassMap<OrderHeader>
{
    Id( e => e.Id).GeneratedBy.Native();
    HasMany(e => e.OrderItems).Inverse();
}

public class OrderItemMap : ClassMap<OrderItem>
{
    Id(e => e.Id).GeneratedBy.Native();
    References(e => e.Header).Not.Nullable().AsSet(); // Explicit AsSet
}

So an ISet and the explicit AsSet() on the mapping made the issue go away. This code snippet is very simplified and we had multiple entities in the QueryOver with HasMany() IList - when all were updated to the ISet, it worked properly.

Athanor answered 21/7, 2015 at 14:23 Comment(2)
Do you have a sample of old/new mappings?Krasnodar
@AlexeyZimarev Sure, I have updated my answer with examples of before and after. Hope this is of help to you and anyone else :)Athanor
P
3

I wouldn't worry too much about the hbm itself. FluentNHibernate "compiles" to XML which goes through the mapping layer. NHibernate's own mapping-by-code also uses parts of the same code as hbm files.

Anyway, the mapping code hasn't changed very much. Any regressions are more likely to be in other parts.

Premature answered 26/8, 2014 at 19:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.