【问题标题】:NHibernate.MappingException: No persister for: XYZNHibernate.MappingException:没有持久性:XYZ
【发布时间】:2010-09-08 15:20:08
【问题描述】:

现在,在你说之前:我做过 Google 和我的hbm.xml 文件 嵌入式资源。

这是我调用的代码:

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

这是我的类映射文件:

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

以前有人遇到过这个问题吗?

这是完整的错误信息:

MappingException: No persister for: HQData.Objects.SubCategory]NHibernate.Impl.SessionFactoryImpl.GetEntityPersister(String entityName, Boolean throwIfNotFound)
 在 c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionFactoryImpl.cs:766 NHibernate.Impl.SessionFactoryImpl.GetEntityPersister(String entityName)
 在 c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionFactoryImpl.cs:752 NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent 事件, LoadType loadType)
 在 c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Event\Default\DefaultLoadEventListener.cs:37 NHibernate.Impl.SessionImpl.FireLoad(LoadEvent 事件,LoadType loadType)
 在 c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:2054 NHibernate.Impl.SessionImpl.Get(String entityName, Object id)
 在 c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:1029 NHibernate.Impl.SessionImpl.Get(类型 entityClass,对象 id)
 在 c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:1020 NHibernate.Impl.SessionImpl.Get(对象 id)
 在 c:\CSharp\NH2.0.0\nhibernate\src\NHibernate\Impl\SessionImpl.cs:985 HQData.DataAccessUtils.NHibernateObjectHelper.LoadDataObject(Int32 Id)
 在 C:\Development\HQChannelRepo\HQ Channel Application\HQChannel\HQData\DataAccessUtils\NHibernateObjectHelper.cs:42 HQWebsite.LocalSearch.get_subCategory()
 在 C:\Development\HQChannelRepo\HQ Channel Application\HQChannel\HQWebsite\LocalSearch.aspx.cs:17 HQWebsite.LocalSearch.Page_Load(Object sender, EventArgs e)
 在 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

更新my 场景的解决方案如下:我更改了一些代码,但在运行时没有将程序集添加到配置文件中。

【问题讨论】:

  • 我遇到了同样的错误,但问题不同。 Session.Load("SearchItem",searchItemID) as SearchItem 返回映射错误, Session.Load(searchItemID) 不会(无论如何都是一种不太容易出错的方法。

标签: c# .net nhibernate


【解决方案1】:

在我的情况下,我获取了一个没有 await 的实体:

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

然后我试图删除它:

await _unitOfWork.Session.DeleteAsync(company);

我无法解读我正在删除 Task&lt;Company&gt; 而不是 Company 的错误消息:

MappingException:没有持久性: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,版本=5.3.0.0,文化=中性,PublicKeyToken=aa95f207798dfdb4]]

【讨论】:

    【解决方案2】:

    我有类似的问题,但所有提到的要求都得到了满足。就我而言,我尝试将一些实体类(OBJEKTE 类型)保存回数据库。其他地方确实有效,但仅在这种情况下它会失败并引发此异常。

    我的解决方案(HACK)是重新映射 OBJEKTE 类型的对象,然后存储它。突然它起作用了。但不要问为什么。

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

    如果 inparam 会直接转到 UpdateAsync(),它就找不到匹配的持久化器。

    这可以通过 NH 这样做的方式来解释。它从您的映射类派生一个代理,并实现包含脏处理的属性。看到这个:

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

    有趣的是,inparam 的来源实际上是 NH 存储库本身。无论如何。我下次继续使用这个重新分配技巧。

    【讨论】:

      【解决方案3】:

      googlingstackoverflowing 上花了大约 4 个小时,尝试了所有的东西,我发现了我的错误:

      我的映射文件名为 .nbm.xml 而不是 .hbm.xml。那太疯狂了。

      【讨论】:

      • 啊,只是做了同样的事情,只是我把它当作 .xml 而不是 .hbm.xml。也许错误中应该有一些提示:)
      • 天啊。我不敢相信我做到了。我在映射文件中搜索了几个小时以查找错误,结果发现我在文件名中打错了... doh。谢谢!如果我没有偶然发现这个问题,我会不寒而栗。
      • 哇,太好了——我在这个问题上大发雷霆。查看了我的 xml 文件一百次,无法弄清楚为什么它不像其他文件那样工作。我实际上错过了文件名的“.hbm”部分。谢谢!
      • 你节省了我的时间。谢谢
      【解决方案4】:

      确保您已在 Session 上为您打算从 DB 获取的域对象调用了 CreateCriteria(typeof(DomainObjectType)) 方法。

      【讨论】:

      • 这是持久化,而不是提取。
      【解决方案5】:

      我从here得到这个:

      在我的例子中,映射类不是公开的。换句话说,而不是:

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

      我刚刚:

      class UserMap : ClassMap<user>
      

      【讨论】:

      • 谢谢,你让我免于头疼。 :)
      • 如果您使用的是 Fluent,我会说这是更常见的原因。谢谢,很容易错过。
      • 谢谢!在检查我是否公开了我的映射类时,我发现我没有为这个实体编写映射类 - 哎呀! :) 为我节省了大量时间!
      【解决方案6】:

      由于映射配置无效而发生此错误。您应该检查为会话工厂设置 .Mappings 的位置。基本上在你的项目中搜索“.Mappings(”并确保你在下面的行中指定了正确的实体类。

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

      【讨论】:

      • 谢谢老兄!我切换了我的实体所在的项目!
      【解决方案7】:

      要补充 Amol 的答案,请不要错误地指定 Interface 类类型。 确保指定实现类。 (即不要使用 IDomainObjectType)。不是我犯了这个错误... :)

      【讨论】:

        【解决方案8】:

        我还在初始化期间添加了错误的程序集。我坚持的类在程序集#1 中,我的 .hbm.xml 文件嵌入在程序集#2 中。我更改了cfg.AddAssembly(... 以添加程序集#2(而不是程序集#1)并且一切正常。谢谢!

        【讨论】:

          【解决方案9】:

          我遇到了同样的问题,因为我在 Configuration.AddAssembly() 方法中添加了错误的程序集。

          【讨论】:

            【解决方案10】:

            我的问题是我忘记将 .hbm 放在映射 xml 的名称中。还要确保将其设为嵌入式资源!

            【讨论】:

            • 这也是我的错!
            • 这也是我的问题,在获取时得到与 Q 中相同的错误。尝试查询该类型的所有对象时,没有错误,只是一个空的结果集!
            • Arg——也忘记了 .hbm。谢谢!
            • 很好,我忘记将构建操作切换到嵌入式资源。
            【解决方案11】:

            我遇到了类似的问题,我解决了如下:

            我正在使用 MS SQL 2008,但在 NH 配置中我的方言很糟糕: NHibernate.Dialect.MsSql2005Dialect 如果我将其更正为: NHibernate.Dialect.MsSql2008Dialect 然后一切正常,无一例外“没有持久性:...” 大卫。

            【讨论】:

              【解决方案12】:

              通过 id 查找对象时遇到类似问题... 我所做的只是在类名中使用完全限定名。那是 之前:

              find("Class",id)
              

              对象变成了这样:

              find("assemblyName.Class",id)
              

              【讨论】:

                【解决方案13】:

                不要忘记在 .config 文件中指定映射信息

                例如

                其中 MyApp.Data 是包含您的映射的程序集

                【讨论】:

                  【解决方案14】:

                  一些显而易见的东西,但对于 NHibernate 的新手来说非常有用。

                  所有 XML 映射文件都应被视为嵌入式资源,而不是默认的内容。此选项是通过编辑文件属性中的 Build Action 属性来设置的。

                  然后将 XML 文件嵌入到程序集中,并在 NHibernate 的配置阶段在项目启动时进行解析。

                  【讨论】:

                  • Haleluia,我将它作为Embedded resource,但是当我将它从一台计算机复制到另一台计算机时,该文件丢失了此属性。我挠了挠头好几分钟。
                  • @DragosDurlut 保存项目文件信息的项目文件(.csproj),而不是文件本身。
                  【解决方案15】:

                  如果从单独的程序集在存储库上运行测试,请确保您的 Hibernate.cfg.xml 设置为始终在所述程序集的 bin 目录中输出。这对我们来说并没有发生,我们在某些情况下遇到了上述错误。

                  免责声明:这可能是一个稍微深奥的建议,因为它是我们如何构建存储库集成测试程序集的直接结果(即我们有一个从每个测试程序集到单个 Hibernate.xfg.xml 的符号链接)

                  【讨论】:

                    【解决方案16】:

                    听起来您忘记将映射程序集添加到会话工厂配置中..

                    如果您使用的是 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>
                    .
                    .
                    

                    【讨论】:

                    • 如何在 Fluent NHibernate 中做到这一点,我正在一个 serperate 项目中开发一个模式,所以我无权访问用户程序集?
                    • 如果您不能引用用户程序集,我认为您将无法使用 Fluent NHibernate。
                    【解决方案17】:

                    应该是name="Id"?打字错误是一个可能的原因。

                    接下来将使用非泛型测试进行尝试,以确保您传入了正确的类型参数。

                    你能发布完整的错误信息吗?

                    【讨论】:

                      猜你喜欢
                      • 2014-01-22
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-11-10
                      • 2011-04-26
                      • 1970-01-01
                      • 2016-10-09
                      • 1970-01-01
                      相关资源
                      最近更新 更多