ChatGPT解决这个技术问题 Extra ChatGPT

NHibernate.MappingException: No persister for: XYZ

Now, before you say it: I did Google and my hbm.xml file is an Embedded Resource.

Here is the code I am calling:

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

Here is my mapping file for the class:

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

Has anyone run to this issue before?

Here is the full error message:

MappingException: No persister for: 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 event, LoadType loadType) in c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Event\Default\DefaultLoadEventListener.cs:37 NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, 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(Type entityClass, Object id) in c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:1020 NHibernate.Impl.SessionImpl.Get(Object id) in c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:985 HQData.DataAccessUtils.NHibernateObjectHelper.LoadDataObject(Int32 Id) 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(Object sender, 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(Object sender, 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, here's what the solution for my scenario was: I had changed some code and I wasn't adding the Assembly to the config file during runtime.

I had the same error, but a different issue. Session.Load("SearchItem",searchItemID) as SearchItem returns a mapping error, Session.Load(searchItemID) does not (and is a less error prone way of doing it anyway.

A
Andy S

Sounds like you forgot to add a mapping assembly to the session factory configuration..

If you're using 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>
.
.

How to do this in Fluent NHibernate, i'm developing a pattern in a serperate project, so i don't have access to the user assembly?
If you can't reference the user assembly, I don't think you'll be able to use Fluent NHibernate.
C
Chris Vosnidis

Something obvious, yet quite useful for someone new to NHibernate.

All XML Mapping files should be treated as Embedded Resources rather than the default Content. This option is set by editing the Build Action attribute in the file's properties.

XML files are then embedded into the assembly, and parsed at project startup during NHibernate's configuration phase.


Haleluia, I has it as an Embedded resource, but when I copied it from one computer to another, the file lost this property. I scratched my head for a couple of good minutes.
@DragosDurlut the project file (.csproj) that saves the information of project files, not the file itself.
n
nHibernate User

My issue was that I forgot to put the .hbm in the name of the mapping xml. Also make sure you make it an embedded resource!


That was my mistake too!
This was my problem also, get the same error as in Q when doing get. When trying to query all of the objects of that type, no error, just an empty result set!
Arg--forgot the .hbm too. Thanks!
Nice, I've forgotten to switch build action to the embedded resource.
B
Benjamin Hodgson

I got this off of here:

In my case the mapping class was not public. In other words, instead of:

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

I just had:

class UserMap : ClassMap<user>

Thanks, you just saved me from a bit of a headache. :)
If you're using Fluent, I'd say this would be the more common cause. Thanks, that was very easy to miss.
Thanks! In going to check whether I'd made my mapping classes public or not I discovered I hadn't written a mapping class for this entity - oops!! :) Saved me heaps of time!!
you saved me a couple of hours, thanks a lot
N
Nickmaovich

Spending about 4 hours on googling and stackoverflowing, trying all of stuff around there, i've found my error:

My mapping file was called .nbm.xml instead of .hbm.xml. That was insane.


Argh, just did the same except i had it just as .xml instead of .hbm.xml. Maybe there should be some hints in the errors :)
omg. I cannot believe I did this. I was searching for hours in mapping files for errors and it turns out I had made a typo in the filename... doh. Thank you! I shudder to think how long I would have been tearing my hair out for if I hadn't stumbled across this.
Wow, great catch - I was pulling my hair out on this problem. Looked over my xml file a hundred times and couldn't figure out why it wasn't working like the others. I was actually missing the ".hbm" part of the file name. Thanks!
You saved my hours. Thanks
D
David

I had similar problem, and I solved it as folows:

I working on MS SQL 2008, but in the NH configuration I had bad dialect: NHibernate.Dialect.MsSql2005Dialect if I correct it to: NHibernate.Dialect.MsSql2008Dialect then everything's working fine without a exception "No persister for: ..." David.


I
IdontCareAboutReputationPoints

I had the same problem because I was adding the wrong assembly in Configuration.AddAssembly() method.


S
Seth

I was also adding the wrong assembly during initialization. The class I'm persisting is in assembly #1, and my .hbm.xml file is embedded in assembly #2. I changed cfg.AddAssembly(... to add assembly #2 (instead of assembly #1) and everything worked. Thanks!


g
goku_da_master

To add to Amol's answer, don't make the mistake of specifying the Interface class type. Make sure you specify the implementation class. (Ie. don't use IDomainObjectType). Not that I made this mistake... :)


M
Matt Hinze

Should it be name="Id"? Typos are a likely cause.

Next would be to try it out with a non-generic test to make sure you're passing in the proper type parameter.

Can you post the entire error message?


A
Arkadas Kilic

This error occurs because of invalid mapping configuration. You should check where you set .Mappings for your session factory. Basically search for ".Mappings(" in your project and make sure you specified correct entity class in below line.

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

thanks dude! I switched the project my entities were sitting in!
佚名

If running tests on the repository from a seperate assembly, then make sure your Hibernate.cfg.xml is set to output always in the bin directory of said assembly. This wasn't happening for us and we got the above error in certain circumstances.

Disclaimer: This might be a slightly esoteric bit of advice, given that it's a direct result of how we structure our repository integration test assemblies (i.e. we have a symbolic link from each test assembly to a single Hibernate.xfg.xml)


佚名

Don't forget to specify mapping information in .config file

e.g.

where MyApp.Data is assembly that contains your mappings


J
Jeff Atwood

Had a similar problem when find an object by id... All i did was to use the fully qualified name in the class name. That is Before it was :

find("Class",id)

Object so it became like this :

find("assemblyName.Class",id)

R
RBT

Make sure you have called the CreateCriteria(typeof(DomainObjectType)) method on Session for the domain object which you intent to fetch from DB.


This is a persist, not a fetch.
R
Robetto

I have a similar problem but all mentioned requirements are met. In my case I try to save some entity class (Type of OBJEKTE) back to the DB. Other places do work but only in this case it fails and raises this exception.

My solution (HACK) was to re-map the objet of type OBJEKTE again and store it then. Suddenly it works. But don't ask why.

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

If inparam would go straight to UpdateAsync() it cannot find a matching persistor.

It could be explained by the way NH does this. It derives a proxy from your mapping class and implements the properties with dirty handling included. See this:

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

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

The fun thing though is that the source of inparam is in fact the NH repository itself. Anyways. I stay with this reassign hack for the next time being.


x
xhafan

I my case I fetched an entity without await:

var company = _unitOfWork.Session.GetAsync<Company>(id);

and then I tried to delete it:

await _unitOfWork.Session.DeleteAsync(company);

I could not decipher the error message that I'm deleting a Task<Company> instead of Company:

MappingException: No persister for: System.Runtime.CompilerServices.AsyncTaskMethodBuilder'1+AsyncStateMachineBox'1[[SmartGuide.Core.Domain.Users.Company, SmartGuide.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null],[NHibernate.Impl.SessionImpl+d__54`1[[SmartGuide.Core.Domain.Users.Company, SmartGuide.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]], NHibernate, Version=5.3.0.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4]]


M
Mitja

You would think that after 14 years, all possible answers to this question have been written down. It seems like that is not the case.

In the application I'm currently working on, there are several ISessionFactory instances, each one for a different database.

If you're taking the wrong one to create your ISession, of course it will have no idea of the class you're trying to persist, which was the error in my case.


关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now