136

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.

Jeroen
  • 60,696
  • 40
  • 206
  • 339
Sara Chipps
  • 9,322
  • 11
  • 58
  • 103
  • 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. – Kendrick Aug 10 '10 at 19:31

18 Answers18

101

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>
.
.
Andy S
  • 8,641
  • 6
  • 36
  • 40
  • 7
    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? – Mustafa Magdy Jan 14 '11 at 00:22
  • If you can't reference the user assembly, I don't think you'll be able to use Fluent NHibernate. – Andy S Jan 18 '11 at 17:24
99

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.

Chris Vosnidis
  • 1,311
  • 10
  • 8
  • 1
    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. – Dragos Durlut Jun 02 '11 at 21:43
  • 1
    @DragosDurlut the project file (.csproj) that saves the information of project files, not the file itself. – Wagner Leonardi Sep 04 '14 at 17:31
56

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!

nHibernate User
  • 561
  • 4
  • 2
47

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>
Benjamin Hodgson
  • 42,952
  • 15
  • 108
  • 157
basarat
  • 261,912
  • 58
  • 460
  • 511
30

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.

Nickmaovich
  • 517
  • 6
  • 10
  • 9
    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 :) – Rezler Aug 08 '12 at 14:16
  • 2
    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. – kamui Apr 08 '13 at 08:35
  • 1
    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! – Winger Apr 18 '14 at 22:20
  • 1
    You saved my hours. Thanks – Manjay_TBAG Aug 27 '19 at 14:24
4

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.

David
  • 41
  • 1
3

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... :)

goku_da_master
  • 4,257
  • 1
  • 41
  • 43
3

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

3

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!

Seth
  • 6,514
  • 5
  • 49
  • 58
2

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>())
Arkadas Kilic
  • 2,416
  • 2
  • 20
  • 16
2

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?

Matt Hinze
  • 13,577
  • 3
  • 35
  • 40
1

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

e.g.

where MyApp.Data is assembly that contains your mappings

1

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)

0

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.

Robetto
  • 739
  • 7
  • 20
0

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

xhafan
  • 2,140
  • 1
  • 26
  • 26
0

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)
Jeff Atwood
  • 63,320
  • 48
  • 150
  • 153
0

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.

Mitja
  • 1,969
  • 30
  • 35
0

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

RBT
  • 24,161
  • 21
  • 159
  • 240
Amol
  • 3,977
  • 1
  • 23
  • 24