NHibernate.MappingException: nessun persister per: XYZ


134

Ora, prima di dirlo: ho fatto Google e il mio hbm.xmlfile è una risorsa integrata.

Ecco il codice che sto chiamando:

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

Ecco il mio file di mapping per la classe:

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

Qualcuno ha riscontrato questo problema prima?

Ecco il messaggio di errore completo:

MappingException: nessun persister per: HQData.Objects.SubCategory] NHibernate.Impl.SessionFactoryImpl.GetEntityPersister (String entityName, Boolean throwIfNotFound)
 in c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionFactoryImpl.cs: 766 NHibernate.Impl.SessionFactoryImpl.GetEntityPersister (String entityName)
 in c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionFactoryImpl.cs: 752 NHibernate.Event.Default.DefaultLoadEventListener.OnLoad (evento LoadEvent, LoadType loadType)
 in c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Event \ Default \ DefaultLoadEventListener.cs: 37 NHibernate.Impl.SessionImpl.FireLoad (evento LoadEvent, LoadType loadType)
 in c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 2054 NHibernate.Impl.SessionImpl.Get (String entityName, ID oggetto)
 in c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1029 NHibernate.Impl.SessionImpl.Get (Tipo entityClass, ID oggetto)
 in c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1020 NHibernate.Impl.SessionImpl.Get (ID oggetto)
 in c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 985 HQData.DataAccessUtils.NHibernateObjectHelper.LoadDataObject (ID Int32)
 in C: \ Development \ HQChannelRepo \ HQ Channel Application \ HQChannel \ HQData \ DataAccessUtils \ NHibernateObjectHelper.cs: 42 HQWebsite.LocalSearch.get_subCategory ()
 in C: \ Development \ HQChannelRepo \ HQ Channel Application \ HQChannel \ HQWebsite \ LocalSearch.aspx.cs: 17 HQWebsite.LocalSearch.Page_Load (Mittente oggetto, EventArgs e)
 in 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 (Mittente oggetto, EventArgs e) +33 System.Web.UI.Control.OnLoad (EventArgs e) +99 System.Web.UI.Control.LoadRecursive () +47 System.Web.UI.Page .ProcessRequestMain (booleano includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436

Aggiornamento , ecco la soluzione per il mio scenario: avevo modificato del codice e non stavo aggiungendo l'Assemblea al file di configurazione durante il runtime.


Ho avuto lo stesso errore, ma un problema diverso. Session.load ( "SearchItem", searchItemID) come SearchItem restituisce un errore di mappatura, Session.load <SearchItem> (searchItemID) non lo fa (ed è un errore di modo meno inclini di farlo in ogni caso.
Kendrick

Risposte:


101

Sembra che tu abbia dimenticato di aggiungere un assembly di mapping alla configurazione di fabbrica della sessione.

Se stai usando 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
Come farlo in Fluor NHibernate, sto sviluppando un modello in un progetto serperate, quindi non ho accesso all'assemblaggio utente?
Mustafa Magdy,

Se non riesci a fare riferimento all'assemblaggio utente, non credo che sarai in grado di utilizzare Fluent NHibernate.
Andy S,

91

Qualcosa di ovvio, ma abbastanza utile per qualcuno che non conosce NHibernate.

Tutti i file di mapping XML devono essere trattati come risorse incorporate anziché come contenuto predefinito . Questa opzione viene impostata modificando l'attributo Build Action nelle proprietà del file.

I file XML vengono quindi incorporati nell'assembly e analizzati all'avvio del progetto durante la fase di configurazione di NHibernate.


1
Haleluia, ce l'ho come Embedded resource, ma quando l'ho copiato da un computer all'altro, il file ha perso questa proprietà. Mi sono grattato la testa per un paio di minuti buoni.
Dragos Durlut,

1
@DragosDurlut il file di progetto (.csproj) che salva le informazioni dei file di progetto, non il file stesso.
Wagner Leonardi,

50

Il mio problema era che avevo dimenticato di mettere il file .hbm nel nome del mapping xml. Assicurati anche di renderlo una risorsa integrata!


1
Anche quello è stato il mio errore!
Gringo,

Anche questo era il mio problema, quando si ottiene get si ottiene lo stesso errore di Q. Quando si tenta di interrogare tutti gli oggetti di quel tipo, nessun errore, solo un set di risultati vuoto!
Christoph,

Arg: ho dimenticato anche il .hbm. Grazie!
Dr. C. Hilarius,

42

Ho ottenuto questo da qui :

Nel mio caso la classe di mappatura non era pubblica. In altre parole, invece di:

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

Ho appena avuto:

class UserMap : ClassMap<user>

Grazie, mi hai appena salvato da un po 'di mal di testa. :)
Rytmis,

2
Se stai usando Fluent, direi che questa sarebbe la causa più comune. Grazie, è stato molto facile perdere.
Richard Neil Ilagan,

1
Grazie! Nel verificare se avevo reso pubbliche le mie classi di mappatura o meno, ho scoperto di non aver scritto una classe di mappatura per questa entità - oops !! :) Mi ha salvato un sacco di tempo !!
Jen,

28

Trascorrere circa 4 ore in googling e stackoverflow , provando tutte le cose lì intorno, ho trovato il mio errore:

Il mio file di mapping è stato chiamato .nbm.xml anziché .hbm.xml . Era folle.


9
Argh, ha fatto lo stesso, tranne per il fatto che l'ho avuto solo come .xml anziché .hbm.xml. Forse ci dovrebbero essere alcuni suggerimenti negli errori :)
Rezler

2
Oh mio Dio. Non posso credere di averlo fatto. Stavo cercando ore nel mappare i file per errori e si è scoperto che avevo fatto un refuso nel nome del file ... doh. Grazie! Rabbrividisco nel pensare a quanto tempo mi sarei strappato i capelli se non mi fossi imbattuto in questo.
Kamui,

1
Wow, ottima cattura - mi stavo togliendo i capelli per questo problema. Ho esaminato il mio file xml centinaia di volte e non sono riuscito a capire perché non funzionasse come gli altri. In realtà mi mancava la parte ".hbm" del nome del file. Grazie!
Ala

Mi hai salvato le ore. Grazie
Manjay_TBAG il

4

Ho avuto un problema simile e l'ho risolto come gente:

Sto lavorando su MS SQL 2008, ma nella configurazione NH avevo un dialetto errato: NHibernate.Dialect. MsSql2005Dialect se lo correggo a: NHibernate.Dialect. MsSql2008Dialect quindi tutto funziona bene senza eccezioni "Non persisterò per: ..." David.


3

Inoltre stavo aggiungendo l'assemblaggio sbagliato durante l'inizializzazione. La classe che persisto è nell'assembly # 1 e il mio file .hbm.xml è incorporato nell'assembly # 2. Ho cambiato cfg.AddAssembly(...per aggiungere l'assembly # 2 (invece dell'assembly # 1) e tutto ha funzionato. Grazie!


3

Per aggiungere alla risposta di Amol, non commettere l'errore di specificare il tipo di classe Interface. Assicurati di specificare la classe di implementazione . (Vale a dire, non usare IDomainObjectType). Non che abbia fatto questo errore ... :)


2

Dovrebbe essere name="Id"? I Typos sono una causa probabile.

Il prossimo sarebbe di provarlo con un test non generico per assicurarti di passare il parametro di tipo corretto.

Puoi pubblicare l'intero messaggio di errore?



2

Questo errore si verifica a causa di una configurazione di mapping non valida. Dovresti controllare dove hai impostato .Mappings per la tua sessione factory. Fondamentalmente cerca ".Mappings (" nel tuo progetto e assicurati di aver specificato la classe di entità corretta nella riga sotto.

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

grazie amico! Ho cambiato il progetto in cui si trovavano le mie entità!
vigore

1

Se si eseguono test sul repository da un assembly separato, assicurarsi che Hibernate.cfg.xml sia impostato per l'output sempre nella directory bin di detto assembly. Questo non stava accadendo per noi e abbiamo riscontrato l'errore sopra riportato in determinate circostanze.

Dichiarazione di non responsabilità: questo potrebbe essere un consiglio leggermente esoterico, dato che è un risultato diretto del modo in cui strutturiamo i nostri assiemi di test di integrazione del repository (ovvero abbiamo un collegamento simbolico da ciascun assemblaggio di test a un singolo Hibernate.xfg.xml)


1

Non dimenticare di specificare le informazioni sulla mappatura nel file .config

per esempio

dove MyApp.Data è un assembly che contiene i mapping


0

Ho avuto un problema simile quando ho trovato un oggetto per id ... Tutto quello che ho fatto è stato utilizzare il nome completo nel nome della classe. Cioè prima che fosse:

find("Class",id)

Oggetto così è diventato così:

find("assemblyName.Class",id)

0

Assicurarsi di aver chiamato il CreateCriteria(typeof(DomainObjectType))metodo su Session per l'oggetto di dominio che si intende recuperare dal DB.


Questo è un persistente, non un recupero.
Joshua Drake,

0

Ho un problema simile ma tutti i requisiti menzionati sono soddisfatti. Nel mio caso provo a salvare nel DB una classe di entità (Tipo di OBJEKTE). Altri posti funzionano ma solo in questo caso fallisce e solleva questa eccezione.

La mia soluzione (HACK) era quella di mappare nuovamente l'oggetto di tipo OBJEKTE e di memorizzarlo poi. Improvvisamente funziona. Ma non chiederti perché.

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

Se inparam andrebbe direttamente su UpdateAsync () non riuscirà a trovare una persistenza corrispondente.

Potrebbe essere spiegato dal modo in cui NH fa questo. Deriva un proxy dalla classe di mappatura e implementa le proprietà con gestione sporca inclusa. Guarda questo:

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

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

La cosa divertente è che la fonte inparamè in realtà il repository NH stesso. In ogni modo. Rimango con questo hack di riassegnazione per la prossima volta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.