NHibernate.MappingException: Tidak ada persister untuk: XYZ

135

Sekarang, sebelum Anda mengatakannya: Saya membuat Google dan hbm.xmlfile saya adalah Sumber Daya Tersemat.

Ini kode yang saya panggil:

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

Berikut adalah file pemetaan saya untuk kelas tersebut:

<?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>

Adakah yang pernah mengalami masalah ini sebelumnya?

Ini pesan kesalahan lengkapnya:

MappingException: Tidak ada persister untuk: HQData.Objects.SubCategory] NHibernate.Impl.SessionFactoryImpl.GetEntityPersister (String entityName, Boolean throwIfNotFound)
 di c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionFactoryImpl.cs: 766 NHibernate.Impl.SessionFactoryImpl.GetEntityPersister (String entityName)
 di c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionFactoryImpl.cs: 752 NHibernate.Event.Default.DefaultLoadEventListener.OnLoad (acara LoadEvent, LoadType loadType)
 di c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Event \ Default \ DefaultLoadEventListener.cs: 37 NHibernate.Impl.SessionImpl.FireLoad (acara LoadEvent, LoadType loadType)
 di c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 2054 NHibernate.Impl.SessionImpl.Get (String entityName, Object id)
 di c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1029 NHibernate.Impl.SessionImpl.Get (Ketik entityClass, Object id)
 di c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1020 NHibernate.Impl.SessionImpl.Get (Object id)
 di c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 985 HQData.DataAccessUtils.NHibernateObjectHelper.LoadDataObject (Int32 Id)
 di C: \ Development \ HQChannelRepo \ HQ Channel Application \ HQChannel \ HQData \ DataAccessUtils \ NHibernateObjectHelper.cs: 42 HQWebsite.LocalSearch.get_subCategory ()
 di C: \ Development \ HQChannelRepo \ HQ Channel Application \ HQChannel \ HQWebsite \ LocalSearch.aspx.cs: 17 HQWebsite.LocalSearch.Page_Load (Pengirim objek, EventArgs e)
 di 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 (pengirim Objek, 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

Perbarui , inilah solusi untuk skenario saya : Saya telah mengubah beberapa kode dan saya tidak menambahkan Majelis ke file konfigurasi selama runtime.

Sara Chipps
sumber
Saya mengalami kesalahan yang sama, tetapi masalah yang berbeda. Session.load ( "SearchItem", searchItemID) sebagai SearchItem mengembalikan kesalahan pemetaan, session.load <SearchItem> (searchItemID) tidak (dan merupakan kesalahan kurang cara rawan melakukannya pula.
Kendrick

Jawaban:

102

Kedengarannya Anda lupa menambahkan rakitan pemetaan ke konfigurasi pabrik sesi ..

Jika Anda menggunakan 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>
.
.
Andy S
sumber
7
Bagaimana melakukan ini di Fluent NHibernate, saya mengembangkan pola dalam proyek serperate, jadi saya tidak memiliki akses ke rakitan pengguna?
Mustafa Magdy
Jika Anda tidak dapat merujuk rakitan pengguna, saya rasa Anda tidak akan dapat menggunakan Fluent NHibernate.
Andy S
91

Sesuatu yang jelas, namun cukup berguna bagi seseorang yang baru mengenal NHibernate.

Semua file Pemetaan XML harus diperlakukan sebagai Sumber Daya Tersemat daripada Konten default . Opsi ini ditetapkan dengan mengedit atribut Build Action di properti file.

File XML kemudian disematkan ke dalam assembly, dan diurai saat memulai proyek selama fase konfigurasi NHibernate.

Chris Vosnidis
sumber
1
Haleluia, saya memilikinya sebagai Embedded resource, tetapi ketika saya menyalinnya dari satu komputer ke komputer lain, file tersebut kehilangan properti ini. Aku menggaruk kepalaku selama beberapa menit.
Dragos Durlut
1
@DragosDurlut file proyek (.csproj) yang menyimpan informasi file proyek, bukan file itu sendiri.
Wagner Leonardi
51

Masalah saya adalah bahwa saya lupa meletakkan .hbm di nama xml pemetaan. Pastikan juga Anda menjadikannya sumber daya yang disematkan!

nHibernate User
sumber
1
Itu salahku juga!
Gringo
Ini juga masalah saya, dapatkan kesalahan yang sama seperti di Q saat melakukan get. Saat mencoba untuk menanyakan semua objek dari tipe itu, tidak ada kesalahan, hanya set hasil kosong!
Christoph
Arg - lupa .hbm juga. Terima kasih!
Dr.C.Hilarius
43

Saya mendapatkan ini dari sini :

Dalam kasus saya, kelas pemetaan itu bukan untuk umum. Dengan kata lain, alih-alih:

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

Saya baru saja:

class UserMap : ClassMap<user>
basarat
sumber
Terima kasih, Anda baru saja menyelamatkan saya dari sedikit sakit kepala. :)
Rytmis
2
Jika Anda menggunakan Fluent, menurut saya ini adalah penyebab yang lebih umum. Terima kasih, itu sangat mudah untuk dilewatkan.
Richard Neil Ilagan
1
Terima kasih! Saat akan memeriksa apakah saya telah membuat kelas pemetaan saya menjadi publik atau tidak, saya menemukan bahwa saya belum menulis kelas pemetaan untuk entitas ini - oops !! :) Menyelamatkan saya banyak waktu !!
Jen
28

Menghabiskan sekitar 4 jam untuk googling dan stackoverflowing , mencoba semua hal di sekitar sana, saya menemukan kesalahan saya:

File pemetaan saya dipanggil .nbm.xml bukan hbm.xml . Itu gila.

Nickmaovich
sumber
9
Argh, baru saja melakukan hal yang sama kecuali saya memilikinya seperti .xml, bukan .hbm.xml. Mungkin seharusnya ada beberapa petunjuk dalam kesalahan :)
Rezler
2
ya Tuhan. Saya tidak percaya saya melakukan ini. Saya mencari berjam-jam di file pemetaan untuk kesalahan dan ternyata saya salah ketik di nama file ... doh. Terima kasih! Aku ngeri membayangkan berapa lama aku akan mencabut rambutku jika aku tidak menemukan ini.
kamui
1
Wow, hasil yang bagus - Saya berusaha mengatasi masalah ini. Memeriksa file xml saya ratusan kali dan tidak tahu mengapa tidak berfungsi seperti yang lain. Saya sebenarnya kehilangan bagian ".hbm" dari nama file. Terima kasih!
Pemain sayap
1
Anda menghemat waktu saya. Terima kasih
Manjay_TBAG
4

Saya memiliki masalah yang sama, dan saya menyelesaikannya sebagai berikut:

Saya mengerjakan MS SQL 2008, tetapi dalam konfigurasi NH saya memiliki dialek yang buruk: NHibernate.Dialect. MsSql2005Dialect jika saya mengoreksinya ke: NHibernate.Dialect. MsSql2008Dialect maka semuanya bekerja dengan baik tanpa terkecuali "No persister for: ..." David.

David
sumber
3

Saya juga menambahkan perakitan yang salah selama inisialisasi. Kelas yang saya pertahankan sedang dalam perakitan # 1, dan file .hbm.xml saya disematkan dalam perakitan # 2. Saya berubah cfg.AddAssembly(...untuk menambahkan perakitan # 2 (bukan perakitan # 1) dan semuanya bekerja. Terima kasih!

Seth
sumber
3

Untuk menambah jawaban Amol, jangan membuat kesalahan dengan menentukan tipe kelas Interface. Pastikan Anda menentukan kelas implementasi . (Yaitu. Jangan gunakan IDomainObjectType). Bukannya saya melakukan kesalahan ini ... :)

goku_da_master
sumber
2

Haruskah itu name="Id" ? Salah ketik adalah kemungkinan penyebabnya.

Berikutnya adalah mencobanya dengan pengujian non-umum untuk memastikan Anda meneruskan parameter type yang tepat.

Bisakah Anda memposting seluruh pesan kesalahan?

Matt Hinze
sumber
2

Saya mengalami masalah yang sama karena saya menambahkan assembly yang salah dalam metode Configuration.AddAssembly ().

IdontCareAboutReputationPoints
sumber
2

Kesalahan ini terjadi karena konfigurasi pemetaan tidak valid. Anda harus memeriksa di mana Anda mengatur .Mappings untuk pabrik sesi Anda. Pada dasarnya cari ".Mappings (" dalam proyek Anda dan pastikan Anda menentukan kelas entitas yang benar di baris di bawah ini.

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<YourEntityClassName>())
Arkadas Kilic
sumber
Terima kasih Bung! Saya mengganti proyek tempat entitas saya duduk!
viggity
1

Jika menjalankan tes pada repositori dari rakitan terpisah, pastikan Hibernate.cfg.xml Anda disetel ke keluaran selalu di direktori bin rakitan tersebut. Ini tidak terjadi pada kami dan kami mendapatkan kesalahan di atas dalam keadaan tertentu.

Penafian: Ini mungkin sedikit saran esoteris, mengingat ini adalah hasil langsung dari bagaimana kami menyusun rakitan pengujian integrasi repositori kami (yaitu kami memiliki tautan simbolis dari setiap perakitan pengujian ke Hibernate.xfg.xml tunggal)


sumber
1

Jangan lupa untuk menentukan informasi pemetaan dalam file .config

misalnya

di mana MyApp.Data adalah rakitan yang berisi pemetaan Anda


sumber
0

Punya masalah serupa ketika menemukan objek dengan id ... Yang saya lakukan adalah menggunakan nama yang memenuhi syarat dalam nama kelas. Itu Sebelum itu:

find("Class",id)

Obyek jadi menjadi seperti ini:

find("assemblyName.Class",id)
Jeff Atwood
sumber
0

Pastikan Anda telah memanggil CreateCriteria(typeof(DomainObjectType))metode pada Sesi untuk objek domain yang ingin Anda ambil dari DB.

Amol
sumber
Ini bertahan, bukan pengambilan.
Joshua Drake
0

Saya memiliki masalah serupa tetapi semua persyaratan yang disebutkan terpenuhi. Dalam kasus saya, saya mencoba menyimpan beberapa kelas entitas (Jenis OBJEKTE) kembali ke DB. Tempat lain memang berfungsi tetapi hanya dalam kasus ini gagal dan memunculkan pengecualian ini.

Solusi saya (HACK) adalah memetakan ulang objek jenis OBJEKTE lagi dan menyimpannya kemudian. Tiba-tiba berhasil. Tapi jangan tanya kenapa.

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

Jika inparam akan langsung ke UpdateAsync () itu tidak dapat menemukan persistor yang cocok.

Ini bisa dijelaskan dengan cara NH melakukan ini. Ini mendapatkan proxy dari kelas pemetaan Anda dan mengimplementasikan properti dengan penanganan kotor yang disertakan. Lihat ini:

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

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

Yang menyenangkan adalah bahwa sumber inparamsebenarnya adalah repositori NH itu sendiri. Ngomong-ngomong. Saya tetap dengan peretasan penugasan ulang ini untuk waktu berikutnya.

Robetto
sumber