NHibernate.MappingException: Kein Persister für: XYZ

134

Bevor Sie es sagen: Ich habe Google verwendet und meine hbm.xmlDatei ist eine eingebettete Ressource.

Hier ist der Code, den ich anrufe:

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

Hier ist meine Zuordnungsdatei für die Klasse:

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

Hat jemand schon einmal auf dieses Problem gestoßen?

Hier ist die vollständige Fehlermeldung:

MappingException: Kein Persister für: 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 (LoadEvent-Ereignis, LoadType loadType)
 in c: \ CSharp \ NH2.0.0 \ nHibernate \ src \ NHibernate \ Event \ Default \ DefaultLoadEventListener.cs: 37 NHibernate.Impl.SessionImpl.FireLoad (LoadEvent-Ereignis, LoadType loadType)
 in c: \ CSharp \ NH2.0.0 \ nHibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 2054 NHibernate.Impl.SessionImpl.Get (String entityName, Object id)
 in c: \ CSharp \ NH2.0.0 \ nHibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1029 NHibernate.Impl.SessionImpl.Get (Typ entityClass, Objekt-ID)
 in c: \ CSharp \ NH2.0.0 \ nHibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1020 NHibernate.Impl.SessionImpl.Get (Objekt-ID)
 in c: \ CSharp \ NH2.0.0 \ nHibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 985 HQData.DataAccessUtils.NHibernateObjectHelper.LoadDataObject (Int32-ID)
 in C: \ Entwicklung \ HQChannelRepo \ HQ-Kanalanwendung \ HQChannel \ HQData \ DataAccessUtils \ NHibernateObjectHelper.cs: 42 HQWebsite.LocalSearch.get_subCategory ()
 in C: \ Entwicklung \ HQChannelRepo \ HQ-Kanalanwendung \ HQChannel \ HQWebsite \ LocalSearch.aspx.cs: 17 HQWebsite.LocalSearch.Page_Load (Objektabsender, EventArgs e)
 in C: \ Entwicklung \ HQChannelRepo \ HQ-Kanalanwendung \ HQChannel \ HQWebsite \ LocalSearch.aspx.cs: 27 System.Web.Util.CalliHelper.EventArgFunctionCaller (IntPtr fp, Objekt o, Objekt t, EventArgs e) +15 System.Web .Util.CalliEventHandlerDelegateProxy.Callback (Objektabsender, 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

Update , hier ist die Lösung für mein Szenario: Ich hatte Code geändert und habe die Assembly zur Laufzeit nicht zur Konfigurationsdatei hinzugefügt.

Sara Chipps
quelle
Ich hatte den gleichen Fehler, aber ein anderes Problem. Session.Load ("SearchItem", searchItemID) als SearchItem einen Zuordnungsfehler zurückgibt, Session.Load <SearchItem> (searchItemID) nicht (und ist sowieso eine weniger fehleranfällige Methode).
Kendrick

Antworten:

101

Klingt so, als hätten Sie vergessen, der Session Factory-Konfiguration eine Mapping-Assembly hinzuzufügen.

Wenn Sie app.config verwenden ...

.
.
    <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.
quelle
7
Wie mache ich das in Fluent NHibernate? Ich entwickle ein Muster in einem serpierten Projekt, damit ich keinen Zugriff auf die Benutzerassembly habe.
Mustafa Magdy
Wenn Sie nicht auf die Benutzerassembly verweisen können, können Sie Fluent NHibernate nicht verwenden.
Andy S
91

Etwas Offensichtliches, aber für jemanden, der neu bei NHibernate ist, sehr nützlich.

Alle XML-Zuordnungsdateien sollten als behandelt werden eingebettete Ressourcen statt der standardmäßigen Inhalt . Diese Option wird festgelegt, indem das Attribut Build Action in den Eigenschaften der Datei bearbeitet wird.

XML-Dateien werden dann in die Assembly eingebettet und beim Projektstart während der Konfigurationsphase von NHibernate analysiert.

Chris Vosnidis
quelle
1
Haleluia, ich habe es als Embedded resource, aber als ich es von einem Computer auf einen anderen kopierte, verlor die Datei diese Eigenschaft. Ich kratzte mir ein paar gute Minuten am Kopf.
Dragos Durlut
1
@DragosDurlut die Projektdatei (.csproj), die die Informationen der Projektdateien speichert, nicht die Datei selbst.
Wagner Leonardi
50

Mein Problem war, dass ich vergessen habe, die .hbm in den Namen der Mapping-XML zu setzen. Stellen Sie außerdem sicher, dass Sie es zu einer eingebetteten Ressource machen!

nHibernate-Benutzer
quelle
1
Das war auch mein Fehler!
Gringo
Dies war auch mein Problem, erhalten Sie den gleichen Fehler wie in Q, wenn Sie get bekommen. Beim Versuch, alle Objekte dieses Typs abzufragen, kein Fehler, nur eine leere Ergebnismenge!
Christoph
Arg - habe auch die .hbm vergessen. Vielen Dank!
Dr. C. Hilarius
42

Ich habe das hier rausgebracht :

In meinem Fall war die Mapping-Klasse nicht öffentlich. Mit anderen Worten, anstatt:

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

Ich hatte gerade:

class UserMap : ClassMap<user>
Basarat
quelle
Danke, du hast mich gerade vor ein bisschen Kopfschmerzen bewahrt. :)
Rytmis
2
Wenn Sie Fluent verwenden, würde ich sagen, dass dies die häufigste Ursache ist. Danke, das war sehr leicht zu übersehen.
Richard Neil Ilagan
1
Vielen Dank! Als ich überprüfte, ob ich meine Mapping-Klassen veröffentlicht hatte oder nicht, stellte ich fest, dass ich keine Mapping-Klasse für diese Entität geschrieben hatte - oops !! :) Hat mir jede Menge Zeit gespart !!
Jen
28

Ich verbringe ungefähr 4 Stunden mit Googeln und Überlaufen von Stapeln und probiere alles dort aus. Ich habe meinen Fehler gefunden:

Meine Zuordnungsdatei hieß .nbm.xml anstelle von .hbm.xml . Das war verrückt.

Nickmaovich
quelle
9
Argh, habe genau das Gleiche getan, außer dass ich es nur als .xml anstelle von .hbm.xml hatte. Vielleicht sollte es einige Hinweise in den Fehlern geben :)
Rezler
2
Oh mein Gott. Ich kann nicht glauben, dass ich das getan habe. Ich habe stundenlang in Mapping-Dateien nach Fehlern gesucht und es stellte sich heraus, dass ich einen Tippfehler im Dateinamen gemacht hatte ... doh. Danke dir! Ich schaudere bei dem Gedanken, wie lange ich mir die Haare ausgerissen hätte, wenn ich nicht darüber gestolpert wäre.
Kamui
1
Wow, toller Fang - ich habe mir bei diesem Problem die Haare ausgezogen. Ich habe meine XML-Datei hundert Mal durchgesehen und konnte nicht herausfinden, warum sie nicht wie die anderen funktionierte. Mir fehlte tatsächlich der Teil ".hbm" des Dateinamens. Vielen Dank!
Flügelspieler
Du hast meine Stunden gerettet. Danke
Manjay_TBAG
4

Ich hatte ein ähnliches Problem und löste es wie folgt:

Ich arbeite an MS SQL 2008, aber in der NH-Konfiguration hatte ich einen schlechten Dialekt: NHibernate.Dialect.MsSql2005Dialect, wenn ich es korrigiere zu: NHibernate.Dialect. MsSql2008Dialect dann funktioniert ausnahmslos alles einwandfrei "No persister for: ..." David.

David
quelle
3

Ich habe während der Initialisierung auch die falsche Assembly hinzugefügt. Die Klasse, die ich beibehalten habe, befindet sich in Assembly Nr. 1, und meine Datei .hbm.xml ist in Assembly Nr. 2 eingebettet. Ich habe geändert cfg.AddAssembly(..., um Baugruppe 2 (anstelle von Baugruppe 1) hinzuzufügen, und alles hat funktioniert. Vielen Dank!

Seth
quelle
3

Machen Sie nicht den Fehler, den Interface-Klassentyp anzugeben, um Amols Antwort zu ergänzen. Stellen Sie sicher, dass Sie die Implementierungsklasse angeben . (Dh IDomainObjectType nicht verwenden). Nicht dass ich diesen Fehler gemacht hätte ... :)

goku_da_master
quelle
2

Sollte es sein name="Id"? Tippfehler sind eine wahrscheinliche Ursache.

Als nächstes sollten Sie es mit einem nicht generischen Test ausprobieren, um sicherzustellen, dass Sie den richtigen Typparameter übergeben.

Können Sie die gesamte Fehlermeldung posten?

Matt Hinze
quelle
2

Ich hatte das gleiche Problem, weil ich in der Configuration.AddAssembly () -Methode die falsche Assembly hinzugefügt habe.

IdontCareAboutReputationPoints
quelle
2

Dieser Fehler tritt aufgrund einer ungültigen Zuordnungskonfiguration auf. Sie sollten überprüfen, wo Sie .Mappings für Ihre Session Factory festgelegt haben. Suchen Sie grundsätzlich in Ihrem Projekt nach ".Mappings (" und stellen Sie sicher, dass Sie in der folgenden Zeile die richtige Entitätsklasse angegeben haben.

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<YourEntityClassName>())
Arkadas Kilic
quelle
Danke Alter! Ich habe das Projekt gewechselt, in dem meine Entitäten saßen!
Viggity
1

Wenn Sie Tests für das Repository von einer separaten Assembly aus ausführen, stellen Sie sicher, dass Ihre Datei Hibernate.cfg.xml so eingestellt ist, dass sie immer im bin-Verzeichnis dieser Assembly ausgegeben wird. Dies passierte für uns nicht und wir haben unter bestimmten Umständen den oben genannten Fehler erhalten.

Haftungsausschluss: Dies kann ein leicht esoterischer Ratschlag sein, da dies ein direktes Ergebnis der Strukturierung unserer Repository-Integrationstest-Assemblys ist (dh wir haben eine symbolische Verknüpfung von jeder Testassembly zu einer einzelnen Hibernate.xfg.xml).


quelle
1

Vergessen Sie nicht, die Zuordnungsinformationen in der .config-Datei anzugeben

z.B

Dabei ist MyApp.Data eine Assembly, die Ihre Zuordnungen enthält


quelle
0

Hatte ein ähnliches Problem beim Finden eines Objekts anhand der ID ... Ich habe lediglich den vollständig qualifizierten Namen im Klassennamen verwendet. Das ist, bevor es war:

find("Class",id)

Objekt so wurde es so:

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

Stellen Sie sicher, dass Sie die CreateCriteria(typeof(DomainObjectType))Methode für Sitzung für das Domänenobjekt aufgerufen haben, das Sie aus der Datenbank abrufen möchten.

Amol
quelle
Dies ist ein Fortbestehen, kein Abrufen.
Joshua Drake
0

Ich habe ein ähnliches Problem, aber alle genannten Anforderungen sind erfüllt. In meinem Fall versuche ich, eine Entitätsklasse (Typ von OBJEKTE) wieder in der Datenbank zu speichern. Andere Orte funktionieren, aber nur in diesem Fall schlägt dies fehl und löst diese Ausnahme aus.

Meine Lösung (HACK) bestand darin, das Objekt vom Typ OBJEKTE erneut abzubilden und dann zu speichern. Plötzlich funktioniert es. Aber frag nicht warum.

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

Wenn inparam direkt zu UpdateAsync () wechseln würde, kann kein passender Persistor gefunden werden.

Dies könnte durch die Art und Weise erklärt werden, wie NH dies tut. Es leitet einen Proxy von Ihrer Mapping-Klasse ab und implementiert die Eigenschaften mit eingeschlossener Dirty-Behandlung. Sieh dir das an:

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

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

Der Spaß ist jedoch, dass die Quelle inparamtatsächlich das NH-Repository selbst ist. Sowieso. Ich bleibe das nächste Mal bei diesem Neuzuweisungs-Hack.

Robetto
quelle