2

在同一问题上查看了 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)的构建动作设置为嵌入的资源和内容。还将复制设置为输出目录以始终复制。

  2. 将 hibernate-mapping 标签中的 auto-import 设置为 true 和 false

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

  4. 在文件中添加映射资源标签hibernate.cfg.xml会导致映射标签不明确的错误。

我还能尝试什么?错误出现在 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: 
4

1 回答 1

3

我会说,因为所有这些信息,我们应该有一个罪魁祸首。映射C# 代码存在很多问题(实际上是问题)我们肯定知道:

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

如果 NHibernate 会话工厂可以使用这个文件我们会得到这个异常

System.TypeInitializationException:“Instance”的类型初始化程序引发了异常。---> NHibernate.MappingException:无法编译映射文档:NhibernateORM.Mapping.hbm.xml ---> NHibernate.MappingException:持久类布局,未找到 NhibernateORM ---> System.TypeLoadException:无法加载类型'来自程序集 'NhibernateORM 的布局' ...

可以通过将命名空间属性添加到映射来修复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应该是“公共/受保护的虚拟”或“受保护的内部虚拟”...

这可以通过使所有实体的东西虚拟化来解决:

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必须具有以下属性:

  • 构建操作 === 嵌入式资源
  • 复制到输出目录 === 不要复制
于 2015-06-12T05:39:31.813 回答