简体   繁体   中英

NHibernate mapping error ([EntityName] not mapped)

My project (c#, nhibernate, npgsql, nlog) has one entity named Entry and should be mapped to the database table named test . Table contains some test entries.

My application code is as follows:

public void work()
{
    ISessionFactory sessions = new Configuration().Configure().BuildSessionFactory();
    ISession session = sessions.OpenSession();

    IList<Entry> entries = session.CreateQuery("from Entry").List<Entry>();

    foreach (Entry e in entries)
    {
        logger.Debug("Entry: " + e.id + " with " + e.name);
    }
}

The Entry entity looks like this:

namespace pgsql
{
    class Entry
    {
        public virtual int id { get; set; }
        public virtual string name { get; set; }
    }
}

My NHibernate configuration is structured as below:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
        <property name="connection.driver_class">NHibernate.Driver.NpgsqlDriver</property>
        <property name="dialect">NHibernate.Dialect.PostgreSQLDialect</property>
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="default_catalog">test</property>
        <property name="default_schema">test</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hbm2ddl.auto">create</property>
        <property name="connection.connection_string">server=localhost;database=*****;uid=*****;pwd=*****;</property>
    </session-factory>
</hibernate-configuration>

The Entry entity configuration is as follows:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping schema="test" xmlns="urn:nhibernate-mapping-2.2">
    <class name="Entry" table="test">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
    </class>
</hibernate-mapping>

This throws below error:

Entry is not mapped [from Entry]

I have made sure, that Visual Studio is copying all hbm.xml files to the output directory. What am i missing?

Edit in response to your answer:

the solution was to initialize with the Assembly:

 ISessionFactory sessions = new Configuration().Configure().AddAssembly(Assembly.GetExecutingAssembly()).BuildSessionFactory(); 

but i still don't know, why it has to be like that.

I will explain why it has to be like that.

Your entity is defined in same assembly as that of your application.
When you call Configuration().Configure().BuildSessionFactory() , actually all your HBM files are being ignored. You need to do either of following to add HBM file to Configuration instance:

  • Use new Configuration().AddFile("MyFile.hbm.xml") for each individual HBM file.
  • Use new Configuration().Configure().AddAssembly(YourAssembly()) to tell NHibernate to look for all HBM files and add all those for you.
  • Other ways mentioned in document linked below.

As you was not doing either of this, there were no entity configurations added to Configuration . Whey you try to run your HQL query, NHibernate was looking for Entry entity which was not defined (added to Configuration ). Hence was the error.

As you mentioned in your answer, you choose second way to add HBM files to Configuration and issue went away.

Another alternative (probably the best) way is to let NHibernate load all of the mapping files contained in an Assembly:

 Configuration cfg = new Configuration() .AddAssembly( "NHibernate.Auction" ); 

Then NHibernate will look through the assembly for any resources that end with .hbm.xml. This approach eliminates any hardcoded filenames and ensures the mapping files in the assembly get added.

Please refer doc for more details.


Original Answer

Entity name should include namespace as well.

IList<Entry> entries = session.CreateQuery("from pgsql.Entry").List<Entry>();

To make refactoring bit easy, you may also change to something like following:

var queryString = string.Format("from {0}", typeof(Entry));
IList<Entry> entries = session.CreateQuery(queryString).List<Entry>();

Please refer section 14.2. The from clause from docs .

Not a part of your problem but, call to BuildSessionFactory is costly. You do not need to repeat it. You can call it at the startup of your application may be and maintain the instance of ISessionFactory for future use.

the solution was to initialize with the Assembly:

ISessionFactory sessions = new Configuration().Configure().AddAssembly(Assembly.GetExecutingAssembly()).BuildSessionFactory();

but i still don't know, why it has to be like that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM