NHibernate.MappingException:没有持久性:XYZ


134

现在,在您说出来之前:我做了 Google,我的hbm.xml文件 Embedded Resource。

这是我正在调用的代码:

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:对于以下对象没有持久性: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 event,LoadType loadType)
 在c:\ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs:2054 NHibernate.Impl.SessionImpl.Get(字符串entityName,Object id)
 在c:\ CSharp \ NH2.0.0 \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs:1029 NHibernate.Impl.SessionImpl.Get(TypeEntityClass,Object 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(对象发送者,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

更新,这里就是为解决我的情况是:我已经改变了一些代码,我在运行时没有加入大会的配置文件。


我有相同的错误,但问题不同。Session.Load(“ SearchItem”,searchItemID)作为SearchItem返回映射错误,Session.Load <SearchItem>(searchItemID)不会(并且无论如何都是不太容易出错的方式。)
Kendrick 2010年

Answers:


101

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

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

7
如何在Fluent NHibernate中执行此操作,我正在一个复杂的项目中开发模式,因此我无法访问用户程序集?
Mustafa Magdy

如果您不能引用用户程序集,我认为您将无法使用Fluent NHibernate。
安迪·S

91

显而易见的东西,但对于NHibernate新手来说却很有用。

所有XML映射文件都应视为嵌入式资源,而不是默认的Content。通过编辑文件属性中的“构建操作”属性来设置此选项。

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


1
Haleluia,我将其作为Embedded resource,但是当我将其从一台计算机复制到另一台计算机时,该文件丢失了此属性。我scratch了好几分钟。
Dragos Durlut 2011年

1
@DragosDurlut保存项目文件而不是文件本身信息的项目文件(.csproj)。
Wagner Leonardi 2014年


42

我从这里得到的:

就我而言,映射类不是公共的。换句话说,代替:

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

我刚刚有:

class UserMap : ClassMap<user>

谢谢,您让我免于头痛。:)
Rytmis

2
如果您使用的是Fluent,我会说这是更常见的原因。谢谢,这很容易错过。
理查德·尼尔·伊拉根

1
谢谢!在检查是否将映射类公开后,我发现自己没有为此实体编写映射类-哎呀!:)节省了我很多时间!

28

花了大约4个小时在谷歌搜索stackoverflowing上,尝试了周围的所有东西,我发现了自己的错误:

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


9
Argh,除了我拥有.xml而不是.hbm.xml之外,只是做了相同的事情。错误中可能应该有一些提示:)
Rezler 2012年

2
我的天啊。我不敢相信我做到了。我在映射文件中搜索了几个小时以查找错误,结果发现我在文件名中打错了... Doh。谢谢!我不禁思索,如果我没有偶然发现这个头发,我会被扯多久。
kamui

1
哇,好极了-我在解决这个问题。查看了我的xml文件一百次,无法弄清楚为什么它不能像其他文件那样工作。我实际上缺少文件名的“ .hbm”部分。谢谢!
Winger

你节省了我的时间。谢谢
Manjay_TBAG

4

我有类似的问题,我按照以下方法解决了:

我正在使用MS SQL 2008,但是在NH配置中,我的方言错误:NHibernate.Dialect。 如果我将MsSql2005Dialect改正为:NHibernate.Dialect。MsSql2008Dialect 然后一切正常,没有异常“ Nopersist for:...” David。


3

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


3

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


2

应该是name="Id"吗?错别字可能是原因。

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

您可以发布整个错误消息吗?



2

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

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

多谢,伙计!我切换了实体所在的项目!
活力

1

如果从单独的程序集在存储库上运行测试,请确保将Hibernate.cfg.xml设置为始终在该程序集的bin目录中输出。对于我们而言,这不是真的,在某些情况下,我们遇到了上述错误。

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


1

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

例如

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


0

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

find("Class",id)

对象,所以变成这样:

find("assemblyName.Class",id)

0

确保已CreateCriteria(typeof(DomainObjectType))为要从数据库获取的域对象在Session上调用了该方法。


这是持久的,而不是获取。
约书亚·德雷克

0

我有一个类似的问题,但所有提到的要求都得到满足。就我而言,我尝试将一些实体类(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"}

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.