" NHibernate.ObjectNotFoundException:不存在具有给定标识符的行"获得儿童收藏

时间:2016-03-25 14:28:36

标签: c# nhibernate union-subclass

小解释:我有与系列相关的优惠券系列和优惠券。 一些优惠券可以被激活,并且它们存储在单独的表中。 这是我的 .hbm.xml 文件:

<class name="AbstractCoupon" abstract="true">

<id name="Id">
  <generator class="assigned" />
</id>

<property name="Number" not-null="true">
  <column name="Number" length="40" unique-key="UNQ_CouponSeries_Number" index="IDX_CouponSeries_Number" />
</property>

<property name="IsDeleted" not-null="true"/>

<many-to-one name="Series"
             class="iikoNet.Domain.BO.Coupon.CouponSeries"
             column="SeriesId"
             cascade="none"
             lazy="false"
             fetch="join"
             not-null="true"
             unique-key="UNQ_CouponSeries_Number"
             index="IDX_CouponSeries_Number" />

<union-subclass name="Coupon" table="Coupon" />

<union-subclass name="CouponActivated" table="CouponActivated">
  <property name="WhenActivated" not-null="true" />
</union-subclass>

<class name="CouponSeries">

<id name="Id">
  <generator class="assigned" />
</id>

<property name="Name" not-null="true" />
<property name="WhenCreated" type="DateTime" not-null="true" />

<bag name="Coupons" inverse="true" cascade="none" lazy="true" generic="true">
  <cache usage="nonstrict-read-write" />
  <key column="SeriesId" />
  <one-to-many class="AbstractCoupon" />
</bag>

删除其中一张优惠券后

public CouponActivated ActivateCoupon(ISession session, Coupon coupon, DateTimeOffset whenActivated)
        {
            Remove(session, coupon);
            var activatedCoupon = new CouponActivated(coupon, whenActivated);
            Add(session, activatedCoupon);
            return activatedCoupon;
        }

,我正在获取系列中的优惠券列表(.First()是为了简单起见)。

var coupons = session.QueryOver<CouponSeries>()
                .Where(cs => cs.Organization == organization)
                .List()
                .First()
                .Coupons;

当我尝试枚举实体 CouponSeries 的子集合优惠券时,我在这样的完整调用堆栈中得到了上述异常:

NHibernate.ObjectNotFoundException: No row with the given identifier exists[myPrj.Domain.BO.Coupon.AbstractCoupon#85d31f2f-f282-11e5-afb6-50465db51863]
   at NHibernate.Impl.SessionFactoryImpl.DefaultEntityNotFoundDelegate.HandleEntityNotFound(String entityName, Object id)
   at NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
   at NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
   at NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType)
   at NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType)
   at NHibernate.Impl.SessionImpl.InternalLoad(String entityName, Object id, Boolean eager, Boolean isNullable)
   at NHibernate.Type.EntityType.ResolveIdentifier(Object id, ISessionImplementor session)
   at NHibernate.Type.ManyToOneType.Assemble(Object oid, ISessionImplementor session, Object owner)
   at NHibernate.Collection.Generic.PersistentGenericBag`1.InitializeFromCache(ICollectionPersister persister, Object disassembled, Object owner)
   at NHibernate.Cache.Entry.CollectionCacheEntry.Assemble(IPersistentCollection collection, ICollectionPersister persister, Object owner)
   at NHibernate.Event.Default.DefaultInitializeCollectionEventListener.InitializeCollectionFromCache(Object id, ICollectionPersister persister, IPersistentCollection collection, ISessionImplementor source)
   at NHibernate.Event.Default.DefaultInitializeCollectionEventListener.OnInitializeCollection(InitializeCollectionEvent event)
   at NHibernate.Impl.SessionImpl.InitializeCollection(IPersistentCollection collection, Boolean writing)
   at NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing)
   at NHibernate.Collection.AbstractPersistentCollection.Read()
   at NHibernate.Collection.Generic.PersistentGenericBag`1.GetEnumerator()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at myPrj.Converters.CouponSeriesConverter.ToDto(CouponSeries series) in e:\Projects\myPrj\dev\CardService\myPrj.Converters\CouponSeriesConverter.cs:line 14
   at myPrj.Service.Coupons.CouponService.<>c__DisplayClass2.<GetCoupons>b__1(CouponSeries c) in e:\Projects\myPrj\dev\CardService\myPrj.Service\Coupons\CouponService.cs:line 30
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at myPrj.Service.Coupons.CouponService.<>c__DisplayClass2.<GetCoupons>b__0(ISession session) in e:\Projects\myPrj\dev\CardService\myPrj.Service\Coupons\CouponService.cs:line 29
   at myPrj.Common.Hibernate.DAL.HibernateSessionManager.CallTransacted[TResult](Func`2 func, Boolean commit) in e:\Projects\myPrj\dev\CardService\myPrj.Common.Hibernate\DAL\HibernateSessionManager.cs:line 172
   at myPrj.Common.Hibernate.DAL.HibernateSessionManager.CallTransacted[TResult](Func`2 func) in e:\Projects\myPrj\dev\CardService\myPrj.Common.Hibernate\DAL\HibernateSessionManager.cs:line 133
   at myPrj.Service.Coupons.CouponService.GetCoupons(Guid organizationOrNetworkId) in e:\Projects\myPrj\dev\CardService\myPrj.Service\Coupons\CouponService.cs:line 26
   at SyncInvokeGetCoupons(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

有谁知道这件事是什么? 我已尝试将 not-found =&#34;忽略&#34; 设置为多对一,正如他们在许多主题中所建议的那样,但是我的情况并不常见。

1 个答案:

答案 0 :(得分:0)

我的解决方案是使用相同ID 添加新的CouponActivated代替优惠券。

更诚实的是,我不应该为包的成员手动执行Remove()和Add(),而是在父实体上编辑集合+执行Update()。