Разрыв изменений с обновлением NHibernate 4
Я вижу, что нового и исправлено в NHibernate 4.0
Я хотел бы знать, если у кого-то были проблемы с обновлением отображений hbm с NHibernate 3 до 4?
Я боюсь, что больше внимания уделяется беглому составлению карт в эти дни. Я могу проверить на наличие более очевидных критических изменений, но хотел бы знать, были ли какие-то тонкие проблемы, с которыми кто-либо сталкивался в производственной среде, которые поначалу могут быть не столь очевидными.
Это похоже на серьезное обновление, и вы ожидаете, что будет риск регрессии.
3 ответа
К вашему сведению, я обнаружил новую ошибку, которая выдается. Мы используем Mapping By Code, и у нас была сущность, которая имела несколько Bag
сопоставления с Fetch
тип установлен в Join
с NHibernate v 3.3.x. Это больше не разрешено в версии 4.0.x.
Мы получили сообщение об ошибке Cannot simultaneously fetch multiple bags.
, что имеет смысл с тем, что необходимо за кулисами, но технически это следует считать серьезным изменением. NHibernate не был достаточно хорош, чтобы сказать нам, какое отображение вызывало проблему.
Мы испытывали ту же проблему с довольно большой QueryOver
- Cannot simultaneously fetch multiple bags
, с отображениями Nhibernate 4 и FluentNhibernate.
Решение было на наших FluentMaps, чтобы установить AsSet()
(согласно нашим областям поддержки), который в конце концов решил проблему.
В соответствии с запросом в комментарии, вот небольшой пример наших отображений до и после исключения:
Это очень упрощенная демонстрация наших классов, которая вызвала Cannot simultaneously fetch multiple bags
, Абстрактный Entity
класс относится к архитектуре S#Arp lite. До изменений это выглядело примерно так
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();
}
Как вы можете видеть, OrderHeader имеет IList
предметов. Меняя это на
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
}
Так что ISet
и явный AsSet()
на карте сделал проблему уйти. Этот фрагмент кода очень упрощен, и у нас было несколько объектов в QueryOver
с HasMany()
IList
- когда все были обновлены до ISet
, он работал правильно.
Я бы не стал слишком беспокоиться о самом hbm. FluentNHibernate "компилирует" в XML, который проходит через слой отображения. Собственное отображение в коде NHibernate также использует части того же кода, что и файлы hbm.
Во всяком случае, код отображения не сильно изменился. Любые регрессии более вероятны в других частях.