NHibernate.MappingException: Не зберігається для: XYZ


134

Тепер, перш ніж сказати це: я зробив 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 objectName, Boolean castIfNotFound)
 в c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionFactoryImpl.cs: 766 NHibernate.Impl.SessionFactoryImpl.GetEntityPersister (String objectName)
 в 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 objectName, Id об'єкта)
 в c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1029 NHibernate.Impl.SessionImpl.Get (Введіть entitetClass, ідентифікатор об'єкта)
 в 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 Channel Application \ 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 (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436

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


У мене була така ж помилка, але інша проблема. Session.Load ("SearchItem", searchItemID), оскільки SearchItem повертає помилку зі відображенням, Session.Load <SearchItem> (searchItemID) не робить (і це все-таки менш схильний до помилок спосіб.
Кендрік

Відповіді:


101

Здається, ви забули додати збірку відображення до заводської конфігурації сеансу.

Якщо ви використовуєте 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>
.
.

7
Як це зробити у Fluent NHibernate, я розробляю схему в змійовому проекті, тому я не маю доступу до зборів користувачів?
Мустафа Мегді

Якщо ви не можете посилатися на збори користувачів, я не думаю, що ви не зможете використовувати Fluent NHibernate.
Andy S

91

Щось очевидне, але досить корисне для когось нового в NHibernate.

Усі файли картографії XML слід розглядати як вбудовані ресурси, а не вміст за замовчуванням . Цей параметр встановлюється шляхом редагування атрибута Build Action у властивостях файлу.

Потім файли XML вбудовуються в збірку та аналізуються при запуску проекту під час фази конфігурації NHibernate.


1
Haleluia, у мене він є як Embedded resource, але коли я скопіював його з одного комп'ютера на інший, файл втратив цю властивість. Я почухав голову пару хороших хвилин.
Драгош Дурлут

1
@DragosDurlut файл проекту (.csproj), який зберігає інформацію про файли проекту, а не сам файл.
Вагнер Леонарді

50

Моя проблема полягала в тому, що я забув поставити .hbm в ім'я відображення xml. Також переконайтеся, що ви зробите це вбудованим ресурсом!


1
То була і моя помилка!
Грінго

Це була моя проблема також, отримуйте ту ж помилку, що і в Q, коли робите get. При спробі запитувати всі об’єкти цього типу, помилок немає, просто порожній набір результатів!
Крістоф

Arg - також забув .hbm. Дякую!
Доктор К. Гіларіус

42

Я отримав це від звідси :

У моєму випадку клас картографування не був загальнодоступним. Іншими словами, замість:

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

Я щойно мав:

class UserMap : ClassMap<user>

Дякую, ти щойно врятував мене від трохи головного болю. :)
Ритміс

2
Якщо ви використовуєте Fluent, я б сказав, що це буде найпоширенішою причиною. Дякую, це було дуже легко пропустити.
Річард Ніл Ілаган

1
Дякую! Будучи перевіряти, чи зробив я свої класи картографування загальнодоступними чи ні, я виявив, що не написав клас для карти для цієї сутності - ой !! :) Врятувало мені купу часу !!
Джен

28

Витративши близько 4 годин на гуглінг та stackoverflow , пробуючи всі речі там, я виявив свою помилку:

Мій файл відображення називався .nbm.xml замість .hbm.xml . Це було божевільно.


9
Арг, так само зробив, за винятком того, що я мав це як .xml замість .hbm.xml. Можливо, в помилках повинні бути якісь підказки :)
Резлер

2
О Боже мій. Я не можу повірити, що я це зробив. Я годинами шукав у картографуванні файлів помилок, і виявляється, я зробив помилку на друку у назві файлу ... До. Дякую! Я здригаюся, думаючи, як довго я б виривав волосся, якби не натрапив на це.
kamui

1
Вау, чудовий улов - я витягнув волосся з цієї проблеми. Сто разів переглянув мій файл XML і не міг зрозуміти, чому він не працює як інші. Я фактично відсутня ".hbm" частина імені файлу. Дякую!
Вінгер

Ти врятував мої години. Дякую
Manjay_TBAG

4

У мене була аналогічна проблема, і я вирішив її як коси:

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


3

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


3

Щоб додати відповідь Amol, не робіть помилки, вказуючи тип класу Interface. Обов’язково вкажіть клас реалізації . (Тобто не використовуйте IDomainObjectType). Не те, щоб я помилився ... :)


2

Чи має бути name="Id"? Опечатки - вірогідна причина.

Далі слід спробувати це за допомогою нетехнічного тесту, щоб переконатися, що ви переходите у відповідний параметр типу.

Чи можете ви опублікувати все повідомлення про помилку?



2

Ця помилка виникає через неправильну конфігурацію відображення. Ви повинні перевірити, де ви встановили .Карти для фабрики сеансу. В основному шукайте ".Mappings (" у вашому проекті та переконайтесь, що ви вказали правильний клас сутності нижче в рядку).

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

Дякую, чувак! Я змінив проект, в якому сиділи мої суб'єкти!
бадьорість

1

Якщо ви виконуєте тести на сховищі з окремої збірки, то переконайтесь, що ваш Hibernate.cfg.xml встановлений для виведення завжди у каталог бін зазначеної збірки. У нас цього не було, і ми отримали вищезазначені помилки за певних обставин.

Відмова: Це може бути трохи езотеричним порадою, враховуючи, що це прямий результат того, як ми структуруємо наші тестові збори інтеграції репозиторію (тобто у нас є символічне посилання від кожної тестової збірки до одного Hibernate.xfg.xml)


1

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

напр

де MyApp.Data - збірка, яка містить ваші відображення


0

Була аналогічна проблема, коли знаходити об’єкт за id ... Все, що я робив, було використовувати повноцінне ім’я у назві класу. Це було раніше:

find("Class",id)

Об'єкт так став таким:

find("assemblyName.Class",id)

0

Переконайтеся, що ви викликали CreateCriteria(typeof(DomainObjectType))метод на сесії для об’єкта домену, який ви збираєтеся отримати з БД.


Це наполегливість, а не винос.
Джошуа Дрейк

0

У мене є аналогічна проблема, але всі згадані вимоги виконуються. У моєму випадку я намагаюся зберегти деякий клас сутності (Тип 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. Все одно. Я залишаюсь із цим перевлаштуванням наступного разу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.