Little explanation: I have coupon series and coupons linked to the series. Some coupons may ne activated, and they are stored in the separate table. Here are my .hbm.xml files:
<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>
After deleting one of the coupon
public CouponActivated ActivateCoupon(ISession session, Coupon coupon, DateTimeOffset whenActivated)
{
Remove(session, coupon);
var activatedCoupon = new CouponActivated(coupon, whenActivated);
Add(session, activatedCoupon);
return activatedCoupon;
}
, I'm getting the list of coupons in the series (.First() is for simplicity).
var coupons = session.QueryOver<CouponSeries>()
.Where(cs => cs.Organization == organization)
.List()
.First()
.Coupons;
When I try to enumerate children collection Coupons of entity CouponSeries, I'm getting the mentioned exception with the full callstack like this :
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)
Does anyone know what's the matter? I've tried setting not-found="ignore" to many-to-one, as they suggest in many topics, but that has nothing common to my situation.
My solution was to add new CouponActivated instead Coupon, using the same Id.
More honestly, I shouldn't have executed Remove() and Add() manually for the members of bag, but edit collection + execute Update() on parent entity.