NHibernate.MappingException: не сохраняется для: XYZ

Теперь, прежде чем вы скажете это: я сделал Google и мой hbm.xml Файл является встроенным ресурсом.

Вот код, который я звоню:

ISession session = GetCurrentSession();
var returnObject =  session.Get<T>(Id);

Вот мой файл сопоставления для класса:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="HQData.Objects.SubCategory, HQData" table="SubCategory" lazy="true">
    <id name="ID" column="ID" unsaved-value="0">
      <generator class="identity" />
    </id>

    <property name="Name" column="Name" />
    <property name="NumberOfBuckets" column="NumberOfBuckets"  />
    <property name="SearchCriteriaOne" column="SearchCriteriaOne" />

    <bag name="_Businesses" cascade="all">
      <key column="SubCategoryId"/>
      <one-to-many 
         class="HQData.Objects.Business, HQData"/>
    </bag>

    <bag name="_Buckets" cascade="all">
      <key column="SubCategoryId"/>
      <one-to-many
         class="HQData.Objects.Bucket, HQData"/>
    </bag>

  </class>
</hibernate-mapping>

Кто-нибудь раньше сталкивался с этой проблемой?

Вот полное сообщение об ошибке:

MappingException: не сохраняется для:  HQData.Objects.SubCategory]NHibernate.Impl.SessionFactoryImpl.GetEntityPersister(String entityName, Boolean throwIfNotFound)
 в c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionFactoryImpl.cs:766 NHibernate.Impl.SessionFactoryImpl.GetEntityPersister(String entityName)
 в c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionFactoryImpl.cs:752 NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(событие LoadEvent, LoadType loadType)
 в c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Event\Default\DefaultLoadEventListener.cs:37 NHibernate.Impl.SessionImpl.FireLoad(событие LoadEvent, LoadType loadType)
 в c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:2054 NHibernate.Impl.SessionImpl.Get(String entityName, Object id)
 в c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:1029 NHibernate.Impl.SessionImpl.Get(Тип entityClass, Object id)
 в c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:1020 NHibernate.Impl.SessionImpl.Get(идентификатор объекта)
 в c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:985 HQData.DataAccessUtils.NHibernateObjectHelper.LoadDataObject(Int32 Id)
 в C:\Development\HQChannelRepo\HQ Channel Application\HQChannel\HQData\DataAccessUtils\NHibernateObjectHelper.cs:42 HQWebsite.LocalSearch.get_subCategory()
 в C: \ Development \ HQChannelRepo \ Приложение канала HQ \HQChannel\HQWebsite\LocalSearch.aspx.cs:17 HQWebsite.LocalSearch.Page_Load(Отправитель объекта, EventArgs e)
 в C:\Development\HQChannelRepo\HQ Channel Application\HQChannel\HQWebsite\LocalSearch.aspx.cs:27 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Отправитель объекта, EventArgs e) +33 System.Web.UI.Control.OnLoad(EventArgs e) +99 System.Web.UI.Control.LoadRecursive() +47 System.Web.UI.Page.ProcessRequestMain(логическое значение includeStagesBeforeAsyncPoint, логическое значение includeStagesAfterAsyncPoint) +1436

Обновление, вот каково было решение для моего сценария: я изменил некоторый код и не добавлял сборку в файл конфигурации во время выполнения.

18 ответов

Решение

Похоже, вы забыли добавить сборку сопоставления в конфигурацию фабрики сеанса.

Если вы используете app.config...

.
.
    <property name="show_sql">true</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <mapping assembly="Project.DomainModel"/>  <!-- Here -->
</session-factory>
.
.

Что-то очевидное, но довольно полезное для новичка в NHibernate.

Все файлы XML Mapping должны рассматриваться как встроенные ресурсы, а не как контент по умолчанию. Эта опция устанавливается путем редактирования атрибута Build Action в свойствах файла.

Затем XML-файлы встраиваются в сборку и анализируются при запуске проекта на этапе настройки NHibernate.

Моя проблема заключалась в том, что я забыл поставить.hbm в названии сопоставления xml. Также убедитесь, что вы делаете это встроенным ресурсом!

Я получил это отсюда:

В моем случае класс картирования не был публичным. Другими словами, вместо:

public class UserMap : ClassMap<user>  // note the public!

У меня только что был:

class UserMap : ClassMap<user>

Потратив около 4 часов на поиск в Google и переполнение стека, пробуя все вокруг, я нашел свою ошибку:

Мой файл сопоставления назывался .nbm.xml, за исключением .hbm.xml. Это было безумно.

У меня была похожая проблема, и я решил ее следующим образом:

Я работал над MS SQL 2008, но в конфигурации NH у меня был плохой диалект: NHibernate.Dialect. MsSql2005Dialect, если я исправлю это: NHibernate.Dialect. MsSql2008Dialect, тогда все работает нормально, без исключения "Нет сохранения для: ..." Дэвид.

Я также добавил неправильную сборку во время инициализации. Класс, который я сохраняю, находится в сборке № 1, а мой файл.hbm.xml встроен в сборку № 2. Я изменился cfg.AddAssembly(... добавить сборку #2 (вместо сборки #1) и все заработало. Спасибо!

Чтобы добавить к ответу Amol, не делайте ошибку, указав тип класса Interface. Убедитесь, что вы указали класс реализации. (Т.е. не используйте IDomainObjectType). Не то чтобы я сделал эту ошибку...:)

У меня была та же проблема, потому что я добавлял неправильную сборку в методе Configuration.AddAssembly().

Должно ли это быть name="Id"? Опечатки являются вероятной причиной.

Далее следует попробовать его с помощью неуниверсального теста, чтобы убедиться, что вы передаете правильный параметр типа.

Можете ли вы опубликовать все сообщение об ошибке?

Эта ошибка возникает из-за неверной конфигурации сопоставления. Вы должны проверить, где вы установили.Mappings для своей фабрики сессий. В основном ищите ".Mappings(" в вашем проекте и убедитесь, что вы указали правильный класс сущности в строке ниже.

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<YourEntityClassName>())

Если вы запускаете тесты в хранилище из отдельной сборки, убедитесь, что ваш Hibernate.cfg.xml всегда настроен на вывод в каталоге bin указанной сборки. Это не произошло для нас, и мы получили вышеуказанную ошибку при определенных обстоятельствах.

Отказ от ответственности: Это может быть немного эзотерическим советом, учитывая, что это является прямым результатом того, как мы структурируем наши тестовые сборки интеграции репозитория (т.е. у нас есть символическая ссылка из каждой тестовой сборки на один файл Hibernate.xfg.xml)

Не забудьте указать информацию об отображении в файле.config

например

где MyApp.Data - сборка, которая содержит ваши сопоставления

Можно подумать, что за 14 лет все возможные ответы на этот вопрос записаны. Похоже, это не так.

В приложении, над которым я сейчас работаю, есть несколько экземпляры, каждый для отдельной базы данных.

Если вы берете не тот, чтобы создать свой , конечно, он не будет знать, какой класс вы пытаетесь сохранить, что было ошибкой в ​​моем случае.

Была похожая проблема при поиске объекта по идентификатору... Все, что я сделал, это использовал полное имя в имени класса. То есть до этого было:

find("Class",id)

Объект так стал вот так:

find("assemblyName.Class",id)

В моем случае я получил объект без await:

      var company = _unitOfWork.Session.GetAsync<Company>(id);

а затем я попытался удалить его:

      await _unitOfWork.Session.DeleteAsync(company);

Я не мог расшифровать сообщение об ошибке, что я удаляю Task<Company>вместо Company:

MappingException: Нет сохранятеля для: System.Runtime.CompilerServices.AsyncTaskMethodBuilder'1+AsyncStateMachineBox'1[[SmartGuide.Core.Domain.Users.Company, SmartGuide.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null],[NHibernate.Impl.SessionImpl+d__54`1[[SmartGuide.Core.Domain.Users.Company, SmartGuide.Core, версия=2.0.0.0, культура=нейтральная, PublicKeyToken=null]], NHibernate, версия=5.3.0.0, Культура = нейтральная, PublicKeyToken = aa95f207798dfdb4]]

Убедитесь, что вы позвонили CreateCriteria(typeof(DomainObjectType)) метод Session для доменного объекта, который вы собираетесь извлечь из БД.

У меня аналогичная проблема, но все указанные требования соблюдены. В моем случае я пытаюсь сохранить некоторый класс сущности (Тип OBJEKTE) обратно в БД. Другие места работают, но только в этом случае происходит сбой и возникает это исключение.

Мое решение (HACK) заключалось в том, чтобы снова отобразить объект типа OBJEKTE и сохранить его. Вдруг работает. Но не спрашивайте почему.

            OBJEKTE t = _mapper.Map<OBJEKTE>(inparam);
            OBJEKTE res = await _objRepo.UpdateAsync(t);

Если inparam сразу перейдет к UpdateAsync(), он не сможет найти подходящий персистор.

Это можно объяснить тем, как это делает NH. Он наследует прокси от вашего класса сопоставления и реализует свойства с включенной грязной обработкой. Видеть это:

t.GetType()
{Name = "OBJEKTE" FullName = "MyComp.Persistence.OBJEKTE"}

inparam.GetType()
{Name = "OBJEKTEProxyForFieldInterceptor" FullName = "OBJEKTEProxyForFieldInterceptor"}

Но самое интересное в том, что источник inparamна самом деле сам репозиторий NH. В любом случае. Я остаюсь с этим хаком переназначения в следующий раз.

Другие вопросы по тегам