Nhibernate:发生异常的 id 获取器

Posted

技术标签:

【中文标题】Nhibernate:发生异常的 id 获取器【英文标题】:Nhibernate: Exception occurred getter of id 【发布时间】:2015-06-11 23:07:33 【问题描述】:

您好,我得到了例外:

NHibernate.PropertyAccessException 未被用户代码处理 HResult=-2146232832 消息=发生异常 getter SpellenDatabase.Domain.Model.Location.Id Source=NHibernate 堆栈跟踪: bij NHibernate.Properties.BasicPropertyAccessor.BasicGetter.Get(对象 目标) bij NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetIdentifier(对象 实体) bij NHibernate.Persister.Entity.AbstractEntityPersister.GetIdentifier(对象 obj,EntityMode 实体模式) bij NHibernate.Persister.Entity.AbstractEntityPersister.IsTransient(对象 实体,ISessionImplementor 会话) bij NHibernate.Engine.ForeignKeys.IsTransient(String entityName, Object entity, Nullable1 assumed, ISessionImplementor session) bij NHibernate.Event.Default.AbstractSaveEventListener.GetEntityState(Object entity, String entityName, EntityEntry entry, ISessionImplementor source) bij NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event) bij NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) bij NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event) bij NHibernate.Impl.SessionImpl.SaveOrUpdate(String entityName, Object obj) bij NHibernate.Engine.CascadingAction.SaveUpdateCascadingAction.Cascade(IEventSource session, Object child, String entityName, Object anything, Boolean isCascadeDeleteEnabled) bij NHibernate.Engine.Cascade.CascadeToOne(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) bij NHibernate.Engine.Cascade.CascadeAssociation(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) bij NHibernate.Engine.Cascade.CascadeProperty(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) bij NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything) bij NHibernate.Event.Default.AbstractSaveEventListener.CascadeAfterSave(IEventSource source, IEntityPersister persister, Object entity, Object anything) bij NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) bij NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) bij NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) bij NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) bij NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event) bij NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event) bij NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) bij NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event) bij NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj) bij SpellenDatabase.DataLayer.BaseRepository1.SaveOrUpdate(T item) in C:\Users\Gebruiker\Documents\Programmeren\SpellenDatabase\SpellenDatabase.DataLayer\BaseRepository.cs:regel 27 bij SpellenDatabase.Web.Controllers.ActiviteitController.Create(Activiteit 活动)在 C:\Users\Gebruiker\Documents\Programmeren\SpellenDatabase\SpellenDatabase.Web\Controllers\ActiviteitController.cs:regel 81 bij lambda_method(闭包,ControllerBase,对象[]) bij System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase 控制器,对象 [] 参数) bij System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext 控制器上下文,IDictionary2 parameters) bij System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 参数) bij System.Web.Mvc.ControllerActionInvoker.c__DisplayClass15.b__12() bij System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter 过滤器、ActionExecutingContext preContext、Func`1 延续) 内部异常:System.Reflection.TargetException H结果=-2146232829 Message=Het 对象 komt niet overeen 遇到了 het doeltype。 源=mscorlib 堆栈跟踪: bij System.Reflection.RuntimeMethodInfo.CheckConsistency(对象目标) bij System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(对象 obj, BindingFlags invokeAttr,Binder binder,Object[]参数, CultureInfo文化) bij System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] 参数, CultureInfo文化) bij System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo文化) bij System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index) bij NHibernate.Properties.BasicPropertyAccessor.BasicGetter.Get(对象 目标) 内部异常:

在插入带有 Locationusage 的 activiteit 并引用现有位置时出现异常。当我插入一个新位置时,我没有例外。

我希望有人能帮我解决这个问题,我找不到任何帮助

我的课程:

public class Location

    public virtual int Id  get; set; 
    public virtual string Name  get; set; 
    public virtual IEnumerable<LocationUsage> Usage  get; set; 


public class LocationUsage

    public virtual int Id  get; set; 
    public virtual Location Location  get; set; 
    public virtual Activiteit Activiteit  get; set; 
    public virtual string Discription  get; set; 


public class Activiteit

    public virtual int Id  get; set; 
    public virtual string Name  get; set; 
    public virtual string Discription  get; set; 
    public virtual ICollection<Variatie> Variaties  get; set; 
    public virtual int MinAge  get; set; 
    public virtual int MaxAge  get; set; 
    public virtual ActiviteitSoort ActiviteitSoort  get; set; 
    public virtual LocationUsage Location  get; set; 
    public virtual ICollection<MateriaalUseage> Materials  get; set; 

我的映射文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="SpellenDatabase.Domain.Model" assembly="SpellenDatabase.Domain">

  <class name="Location" table="Location">
    <id name="Id" type="Int32">
      <column name="Id" sql-type="int" />
      <generator class="increment" />
    </id>
    <property name="Name">
      <column name="Name" not-null="true" />
    </property>
    <set name="Usage" inverse="true">
      <key column="Id" />
      <one-to-many class="LocationUsage" />
    </set>
  </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="SpellenDatabase.Domain.Model" assembly="SpellenDatabase.Domain">

  <class name="LocationUsage" table="LocationUsage">
    <id name="Id" type="Int32">
      <column name="Id" sql-type="int" />
      <generator class="increment" />
    </id>
    <many-to-one name="Location" class="Location" column="Location" cascade="none" />
    <many-to-one name="Activiteit" class="Activiteit" column="Activiteit" unique="true" />
    <property name="Discription" />
  </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="SpellenDatabase.Domain.Model" assembly="SpellenDatabase.Domain">

  <class name="Activiteit" table="Activiteit">

    <id name="Id">
      <column name="Id" sql-type="int" not-null="true" />
      <generator class="increment" />
    </id>

    <property name="Name">
      <column name="Name" not-null="true" />
    </property>
    <property name="Discription">
      <column name="Discription" not-null="true" />
    </property>
    <property name="MinAge" />
    <property name="MaxAge" />

    <one-to-one name="Location" class="Location" cascade="save-update" />
    <many-to-one name="ActiviteitSoort" class="ActiviteitSoort" column="ActiviteitSoort" />

    <set name="Variaties" cascade="save-update">
      <key column="Id" />
      <one-to-many class="Variatie" />
    </set>

    <set name="Materials" cascade="save-update">
      <key column="Id" />
      <one-to-many class="MateriaalUseage" />
    </set>

  </class>

</hibernate-mapping>

表格:

create table Activiteit(
Id int,
Name varchar(50),
Discription varchar(max),
MinAge int,
MaxAge int,
ActiviteitSoort int,
PRIMARY KEY (Id),
FOREIGN KEY (ActiviteitSoort) REFERENCES ActiviteitSoort(Id))

create table Location (
Id int,
Name varchar(50),
PRIMARY KEY (Id))

create table LocationUsage(
Id int,
Location int,
Activiteit int,
Discription varchar(max),
PRIMARY KEY (Id),
FOREIGN KEY (Activiteit) REFERENCES Activiteit(Id),
FOREIGN KEY (Location) REFERENCES Location(Id))

C#:

ISession session = NHibernateHelper.GetCurrentSession(); 
ITransaction tx = session.BeginTransaction();
try

    session.SaveOrUpdate(item);
    session.Flush();
    tx.Commit();

catch (Exception e)

    tx.Rollback();
    throw;

finally

    NHibernateHelper.CloseSession();

【问题讨论】:

添加了完整的堆栈跟踪,但我确实得到了异常。 然而,locaton 对象具有正确的值,并且 locationusage 是一个新的对象,其 id 为 0,正如预期的那样。 添加了代码,这就是你要找的对吧? 我不是在添加一个新位置,而是在添加一个使用位置的新活动。添加位置从来都不是问题 发现问题,一对一关系映射到错误的类 【参考方案1】:

你做错了一对一。

  <class name="Location" table="Location">
    <id name="Id" type="Int32">
      <column name="Id" sql-type="int" />
      <generator class="increment" />
    </id>

该位置以一对一的方式映射到 Activiteit。这意味着,它共享相同的主键。所以他们不能都有自己的发电机。

看看this great post by Ayende。

说实话,我不会使用一对一。简直太乱了。使用常规的多对一(向 Activiteit 表添加另一个外键)。

【讨论】:

以上是关于Nhibernate:发生异常的 id 获取器的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate 2.1.2 - 如何禁用反射优化器

NHibernate + Fluent NHibernate 异常

NHibernate 2 + Fluent Nhibernate 中等信任

NHibernate 3.3.1 与中等信任错误

NHibernate代码监视

在使用 NHibernate 进行持久性的项目中测试数据模型