NHibernate.MappingException: Pas de persistance pour: XYZ

134

Maintenant, avant de le dire: j'ai fait Google et mon hbm.xmlfichier est une ressource intégrée.

Voici le code que j'appelle:

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

Voici mon fichier de mappage pour 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>

Quelqu'un a-t-il déjà rencontré ce problème?

Voici le message d'erreur complet:

MappingException: Pas de persistance pour: HQData.Objects.SubCategory] NHibernate.Impl.SessionFactoryImpl.GetEntityPersister (String entityName, Boolean throwIfNotFound)
 dans c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionFactoryImpl.cs: 766 NHibernate.Impl.SessionFactoryImpl.GetEntityPersister (String entityName)
 dans c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionFactoryImpl.cs: 752 NHibernate.Event.Default.DefaultLoadEventListener.OnLoad (événement LoadEvent, LoadType loadType)
 dans c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Event \ Default \ DefaultLoadEventListener.cs: 37 NHibernate.Impl.SessionImpl.FireLoad (événement LoadEvent, LoadType loadType)
 dans c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 2054 NHibernate.Impl.SessionImpl.Get (String entityName, Object id)
 dans c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1029 NHibernate.Impl.SessionImpl.Get (Type entityClass, Object id)
 dans c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 1020 NHibernate.Impl.SessionImpl.Get (ID d'objet)
 dans c: \ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: 985 HQData.DataAccessUtils.NHibernateObjectHelper.LoadDataObject (Int32 Id)
 dans C: \ Development \ HQChannelRepo \ HQ Channel Application \ HQChannel \ HQData \ DataAccessUtils \ NHibernateObjectHelper.cs: 42 HQWebsite.LocalSearch.get_subCategory ()
 dans C: \ Development \ HQChannelRepo \ HQ Channel Application \ HQChannel \ HQWebsite \ LocalSearch.aspx.cs: 17 HQWebsite.LocalSearch.Page_Load (Expéditeur d'objet, EventArgs e)
 dans 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 (Expéditeur de l'objet, EventArgs e) +33 System.Web.UI.Control.OnLoad (EventArgs e) +99 System.Web.UI.Control.LoadRecursive () +47 System.Web.UI.Page .ProcessRequestMain (booléen includeStagesBeforeAsyncPoint, booléen includeStagesAfterAsyncPoint) +1436

Mise à jour , voici la solution pour mon scénario: j'avais changé du code et je n'ajoutais pas l'assembly au fichier de configuration pendant l'exécution.

Sara Chipps
la source
J'ai eu la même erreur, mais un problème différent. Session.Load ("SearchItem", searchItemID) comme SearchItem renvoie une erreur de mappage, Session.Load <SearchItem> (searchItemID) ne le fait pas (et est de toute façon une façon moins sujette aux erreurs de le faire.
Kendrick

Réponses:

101

On dirait que vous avez oublié d'ajouter un assemblage de mappage à la configuration de la fabrique de session.

Si vous utilisez 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
la source
7
Comment faire cela dans Fluent NHibernate, je développe un modèle dans un projet serperate, donc je n'ai pas accès à l'assembly utilisateur?
Mustafa Magdy le
Si vous ne pouvez pas référencer l'assembly utilisateur, je ne pense pas que vous pourrez utiliser Fluent NHibernate.
Andy S
91

Quelque chose d'évident, mais tout à fait utile pour quelqu'un de nouveau sur NHibernate.

Tous les fichiers de mappage XML doivent être traités comme des ressources incorporées plutôt que comme du contenu par défaut . Cette option est définie en modifiant l'attribut Action de construction dans les propriétés du fichier.

Les fichiers XML sont ensuite intégrés dans l'assembly et analysés au démarrage du projet pendant la phase de configuration de NHibernate.

Chris Vosnidis
la source
1
Haleluia, je l'ai comme un Embedded resource, mais quand je l'ai copié d'un ordinateur à un autre, le fichier a perdu cette propriété. Je me suis gratté la tête pendant quelques bonnes minutes.
Dragos Durlut
1
@DragosDurlut le fichier de projet (.csproj) qui enregistre les informations des fichiers de projet, pas le fichier lui-même.
Wagner Leonardi le
50

Mon problème était que j'avais oublié de mettre le .hbm dans le nom du mappage xml. Assurez-vous également d'en faire une ressource intégrée!

Utilisateur nHibernate
la source
1
C'était aussi mon erreur!
Gringo
C'était aussi mon problème, obtenir la même erreur que dans Q en faisant get. Lorsque vous essayez d'interroger tous les objets de ce type, pas d'erreur, juste un jeu de résultats vide!
Christoph
Arg - j'ai aussi oublié le .hbm. Merci!
Dr C. Hilarius
42

J'ai eu ça d' ici :

Dans mon cas, la classe de mappage n'était pas publique. En d'autres termes, au lieu de:

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

Je viens tout juste d'avoir:

class UserMap : ClassMap<user>
basarat
la source
Merci, vous venez de me sauver d'un petit mal de tête. :)
Rytmis
2
Si vous utilisez Fluent, je dirais que ce serait la cause la plus courante. Merci, c'était très facile à manquer.
Richard Neil Ilagan
1
Merci! En allant vérifier si j'avais rendu mes classes de mapping publiques ou non, j'ai découvert que je n'avais pas écrit de classe de mapping pour cette entité - oups !! :) M'a sauvé beaucoup de temps !!
Jen
28

Passer environ 4 heures sur Google et le stackoverflowing , à essayer tout ce qui se trouve là-bas, j'ai trouvé mon erreur:

Mon fichier de mappage s'appelait .nbm.xml au lieu de .hbm.xml . C'était insensé.

Nickmaovich
la source
9
Argh, j'ai juste fait la même chose sauf que je l'avais juste en .xml au lieu de .hbm.xml. Peut-être qu'il devrait y avoir des indices dans les erreurs :)
Rezler
2
OMG. Je ne peux pas croire que j'ai fait ça. J'ai cherché pendant des heures dans les fichiers de mappage des erreurs et il s'est avéré que j'avais fait une faute de frappe dans le nom du fichier ... doh. Je vous remercie! Je frémis à l'idée depuis combien de temps j'aurais été arraché les cheveux si je n'avais pas trébuché dessus.
kamui
1
Wow, super hic - je tirais mes cheveux sur ce problème. J'ai regardé mon fichier xml cent fois et je n'ai pas pu comprendre pourquoi il ne fonctionnait pas comme les autres. Il me manquait en fait la partie ".hbm" du nom de fichier. Merci!
Ailier
Vous avez sauvé mes heures. Merci
Manjay_TBAG
4

J'ai eu un problème similaire, et je l'ai résolu comme suit:

Je travaille sur MS SQL 2008, mais dans la configuration NH j'avais un mauvais dialecte: NHibernate.Dialect. MsSql2005Dialect si je le corrige à: NHibernate.Dialect. MsSql2008Dialect alors tout fonctionne bien sans exception "Pas de persistance pour: ..." David.

David
la source
3

J'ajoutais également le mauvais assemblage lors de l'initialisation. La classe que je persiste est dans l'assembly n ° 1 et mon fichier .hbm.xml est intégré dans l'assembly n ° 2. J'ai changé cfg.AddAssembly(...pour ajouter l'assemblage n ° 2 (au lieu de l'assemblage n ° 1) et tout a fonctionné. Merci!

Seth
la source
3

Pour ajouter à la réponse d'Amol, ne faites pas l'erreur de spécifier le type de classe Interface. Assurez-vous de spécifier la classe d'implémentation . (Par exemple, n'utilisez pas IDomainObjectType). Non pas que j'ai fait cette erreur ... :)

goku_da_master
la source
2

Doit-il l'être name="Id"? Les fautes de frappe sont une cause probable.

La prochaine étape serait de l'essayer avec un test non générique pour vous assurer que vous passez le paramètre de type approprié.

Pouvez-vous publier l'intégralité du message d'erreur?

Matt Hinze
la source
2

J'ai eu le même problème car j'ajoutais le mauvais assemblage dans la méthode Configuration.AddAssembly ().

IdontCareAboutReputationPoints
la source
2

Cette erreur se produit en raison d'une configuration de mappage non valide. Vous devriez vérifier où vous avez défini .Mappings pour votre fabrique de session. Recherchez essentiellement ".Mappings (" dans votre projet et assurez-vous que vous avez spécifié la classe d'entité correcte dans la ligne ci-dessous.

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<YourEntityClassName>())
Arkadas Kilic
la source
Merci mec! J'ai changé le projet dans lequel mes entités étaient assises!
viggity
1

Si vous exécutez des tests sur le référentiel à partir d'un assembly séparé, assurez-vous que votre Hibernate.cfg.xml est défini pour toujours sortir dans le répertoire bin dudit assembly. Cela ne se produisait pas pour nous et nous avons eu l'erreur ci-dessus dans certaines circonstances.

Avertissement: Cela pourrait être un conseil légèrement ésotérique, étant donné que c'est un résultat direct de la façon dont nous structurons nos assemblys de test d'intégration de référentiel (c'est-à-dire que nous avons un lien symbolique de chaque assemblage de test vers un seul Hibernate.xfg.xml)


la source
1

N'oubliez pas de spécifier les informations de mappage dans le fichier .config

par exemple

où MyApp.Data est l'assembly qui contient vos mappages


la source
0

J'ai eu un problème similaire lors de la recherche d'un objet par identifiant ... Tout ce que j'ai fait était d'utiliser le nom complet dans le nom de la classe. C'est avant qu'il ne soit:

find("Class",id)

Objet donc c'est devenu comme ça:

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

Assurez-vous que vous avez appelé la CreateCriteria(typeof(DomainObjectType))méthode sur Session pour l'objet de domaine que vous avez l'intention d'extraire de DB.

Amol
la source
Ceci est une persistance, pas une récupération.
Joshua Drake
0

J'ai un problème similaire mais toutes les conditions mentionnées sont remplies. Dans mon cas, j'essaie de sauvegarder une classe d'entité (Type d'OBJEKTE) dans la base de données. D'autres endroits fonctionnent mais seulement dans ce cas, cela échoue et lève cette exception.

Ma solution (HACK) était de re-mapper l'objet de type OBJEKTE et de le stocker ensuite. Soudain, ça marche. Mais ne demandez pas pourquoi.

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

Si inparam irait directement à UpdateAsync (), il ne peut pas trouver de persistance correspondante.

Cela pourrait s'expliquer par la manière dont NH fait cela. Il dérive un proxy de votre classe de mappage et implémente les propriétés avec une gestion sale incluse. Regarde ça:

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

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

Ce qui est amusant, c'est que la source de inparam est en fait le référentiel NH lui-même. Bref. Je reste avec ce hack de réaffectation pour la prochaine fois.

Robetto
la source