NHibernate.Mapping异常。 Namespace.className

时间:2015-06-11 18:00:22

标签: c# mysql xml nhibernate nhibernate-configuration

已查看同一问题上的4个stackoverflow帖子,但无法找到解决方案。

我的主要计划:

using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Cfg.MappingSchema;
using NHibernate.Dialect;

namespace NhibernateORM
{
    public class Layout
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public double xCoordinate { get; set; }
        public double yCoordinate { get; set; }
    }
    class Program
    {
        private static int getDummyTableSize(ISession session)
        {
            ITransaction readTx = session.BeginTransaction();
            int size = session.CreateSQLQuery(@"select * from mydb.mytable").List<object>().Count;
            readTx.Rollback();
            return size;
        }

        static void Main(string[] args)
        {
            Configuration config = new Configuration();
            config.Configure(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "hibernate.cfg.xml"));

            ISessionFactory factory = config.BuildSessionFactory();
            ISession session = factory.OpenSession();

            int countBefore = getDummyTableSize(session);

            ITransaction tx = session.BeginTransaction();
            Layout d = new Layout();
            d.Id = 213;
            d.Name = "hello";
            d.xCoordinate = 25.823;
            d.yCoordinate = 746.2;

            // POINT OF ERROR 
            session.Save(d);
            tx.Commit();

            if (countBefore + 1 == getDummyTableSize(session))
            {
                Console.WriteLine("woo hoo");
            }
            else
            {
                Console.WriteLine("oh no");
            }
            session.Close();
        }
    }
}

我的hibernate.cfg.xml(配置文件):

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">
      NHibernate.Connection.DriverConnectionProvider
    </property>
    <property name="connection.driver_class">
      NHibernate.Driver.MySqlDataDriver
    </property>
    <property name="connection.connection_string">
      Server=localhost;Database=mydb;User="root";
    </property>
    <property name="dialect">
      NHibernate.Dialect.MySQL5Dialect
    </property>
    <!--<mapping assembly="NhibernateORM"/>-->
    <!-- mapping files -->
    <!--<mapping resource="Mapping.hbm.xml" />-->
  </session-factory>
</hibernate-configuration>

和我的Mapping.hbm.xml文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NhibernateORM" auto-import="true">
  <class name="Layout" table="mytable">
   <id name="Id" column="ID" type="int">
   </id> 
   <property name="Name" column="name" 
             type="String"></property>
  <property name="xCoordinate" column="xCoordinate" 
             type="double"></property>
<property name="yCoordinate" column="yCoordinate" 
             type="double"></property>
  </class>
</hibernate-mapping>

我尝试了以下内容:

  1. 将映射文件(Mapping.hbm.xml)的构建操作设置为嵌入资源,并将配置文件(hibernate.cfg.xml)的构建操作构建到嵌入式资源和内容。还要将copy复制到输出目录以便始终复制。

  2. 将hibernate-mapping标签中的自动导入设置为true和false

  3. hibernate.cfg.xml中添加映射程序集标记,还检查了命名空间和程序集名称。

  4. hibernate.cfg.xml文件中添加映射资源标记,该标记会产生不明确的映射标记错误。
  5. 我还能尝试什么?在session.save()行之前出现错误,并且在session.save上面的表中检索行数的查询工作正常。

    以下是完整的错误消息:

    NHibernate.MappingException was unhandled
      HResult=-2146232832
      Message=No persister for: NhibernateORM.Layout
      Source=NHibernate
      StackTrace:
           at NHibernate.Impl.SessionFactoryImpl.GetEntityPersister(String entityName)
           at NHibernate.Impl.SessionImpl.GetEntityPersister(String entityName, Object obj)
           at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
           at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
           at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
           at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
           at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
           at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
           at NHibernate.Impl.SessionImpl.Save(Object obj)
           at NhibernateORM.Program.Main(String[] args) in d:\codebase\NhibernateORM\NhibernateORM\Program.cs:line 57
           at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: 
    

1 个答案:

答案 0 :(得分:3)

我说,因为所有这些信息,我们应该有罪魁祸首。使用映射 C#代码(确实问题 )有很多问题,我们肯定知道:

  

Mapping.hbm.xml未正确配置,未使用,对NHibernate

不可见

如果NHibernate会话工厂可以使用这个文件,我们会得到这个例外

  

System.TypeInitializationException:&#39; Instance&#39;的类型初始值设定项抛出一个例外。 ---&GT; NHibernate.MappingException:无法编译映射文档:NhibernateORM.Mapping.hbm.xml ---&gt; NHibernate.MappingException:持久化类布局,找不到NhibernateORM ---&gt; System.TypeLoadException:无法从程序集&#39; NhibernateORM ...

中加载类型&#39; Layout&#39;

可以通过向映射 namespace="NhibernateORM"

添加命名空间属性来解决此问题
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
  assembly="NhibernateORM"
  namespace="NhibernateORM"
  auto-import="true">
  <class name="Layout" table="mytable">
    <id name="Id" column="ID" type="int" generator="assigned" />
    <property name="Name"        column="name"        type="String"/>
    <property name="xCoordinate" column="xCoordinate" type="double" />
    <property name="yCoordinate" column="yCoordinate" type="double" />
  </class>
</hibernate-mapping>

一旦修复,我们以后会得到这个例外

  

NHibernate.InvalidProxyTypeException:以下类型不能用作代理:   NhibernateORM.Layout:方法 get_Id 应该是公共/受保护的虚拟&#39;或者&#39;受保护的内部虚拟&#39; ...

可以通过将所有实体内容设为虚拟来修复:

namespace NhibernateORM
{
    public class Layout
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual double xCoordinate { get; set; }
        public virtual double yCoordinate { get; set; }

所以,当然,我们知道 - 问题是

  • hibernate.cfg.xml
  • 中的错误配置
  • 错误配置 Mapping.hbm.xml 属性

这应该是 hibernate.cfg.xml

的一部分
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
      ...
      <mapping assembly="NhibernateORM"/>
hibernate.cfg.xml 必须具有以下属性:

  • 构建操作===内容
  • 复制到输出目录===始终复制

Mapping.hbm.xml 必须具有以下属性:

  • 构建操作===嵌入式资源
  • 复制到输出目录===不要复制