NHibernate и Composite Key, проблемы с сохранением
От: INsideR Латвия  
Дата: 03.11.07 13:12
Оценка:
Есть такие mappingi:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="ThinkLinks.Data.Domain.AdvertisementSet, ThinkLinks.Data" table="dbo.[BT_AdvertisementSet]" lazy="false">
    <composite-id name="ID" class="ThinkLinks.Data.Domain.AdvertisementSet+DomainObjectID, ThinkLinks.Data">
      <key-property type="System.Int32" name="SetID" column="SetID" />
      <key-many-to-one class="ThinkLinks.Data.Domain.Advertisement, ThinkLinks.Data" name="Advertisement" column="AdvertisementID" />
    </composite-id>
    <property column="AdCPC" type="System.Decimal" name="AdCPC" not-null="true" />
  </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="ThinkLinks.Data.Domain.Advertisement, ThinkLinks.Data" table="dbo.[BT_Advertisement]" lazy="false">

        <id name="AdvertisementID" column="AdvertisementID" type="Int32" unsaved-value="0">
            <generator class="native"/>
        </id>
    <property column="Title" type="String" name="Title" not-null="true" length="200" />
        <property column="url" type="String" name="Url" not-null="true" length="1073741823" />
    <many-to-one name="AdvertisementStatus" column="AdvertisementStatusID" class="ThinkLinks.Data.Domain.AdvertisementStatus, ThinkLinks.Data" />
    <many-to-one name="AdvertisementGroup" column="AdvertisementGroupID" class="ThinkLinks.Data.Domain.AdvertisementGroup, ThinkLinks.Data" />
        <property column="blockreason" type="String" name="BlockReason" length="1073741823" />
    <property column="text" type="String" name="Text" not-null="false" />
    <property column="banner" type="Byte[]" name="Banner" not-null="false" />
    <property column="MinBidPrice" type="Decimal" name="MinBidPrice" />
    <property column="MaxBidPrice" type="Decimal" name="MaxBidPrice"  />
    <many-to-one name="Size" column="SizeID" class="ThinkLinks.Data.Domain.BannerSize, ThinkLinks.Data" />
    <set name="Views">
      <key column="Advertisementid" />
      <one-to-many class="ThinkLinks.Data.Domain.Impressions, ThinkLinks.Data" />
    </set>
    <set name="Clicks">
      <key column="Advertisementid" />
      <one-to-many class="ThinkLinks.Data.Domain.Clicks, ThinkLinks.Data" />
    </set>
    <set name="AdvertisementSets" inverse="false" >
      <key column="AdvertisementID" />
      <one-to-many class="ThinkLinks.Data.Domain.AdvertisementSet, ThinkLinks.Data" />
    </set>
    <!--<set name="Sections" table="BT_WikiSectionAdvertisementXRef" lazy="false">
      <key column="AdvertisementID"/>
      <many-to-many class="ThinkLinks.Data.Domain.Section, ThinkLinks.Data" column="WikiSectionID"/>
    </set>-->
    <many-to-one name="Size" column="SizeID" class="ThinkLinks.Data.Domain.BannerSize, ThinkLinks.Data" />    
    </class>
</hibernate-mapping>



[Serializable]
    public partial class AdvertisementSet : DomainObject<AdvertisementSet.DomainObjectID>
    {
        #region Private Members
        private bool _isChanged;
        private bool _isDeleted;
        private decimal _adCPC;
        #endregion

        [Serializable]
        public class DomainObjectID
        {
            private int _setID;
            private Advertisement _advertisement;

            public DomainObjectID() { }

            public DomainObjectID(int setID, Advertisement adv)
            {
                _setID = setID;
                _advertisement = adv;
            }

            public int SetID
            {
                get { return _setID; }
                protected set { _setID = value; }
            }

            public Advertisement Advertisement
            {
                get { return _advertisement; }
                protected set { _advertisement = value; }
            }

            public override bool Equals(object obj)
            {
                if(obj == this) return true;
                if(obj == null) return false;

                DomainObjectID that = obj as DomainObjectID;
                if(that == null)
                {
                    return false;
                }
                else
                {
                    if(SetID != that.SetID) return false;
                    if(!Advertisement.Equals(that.Advertisement)) return false;
                    return true;
                }
            }

            public override int GetHashCode()
            {
                return Advertisement.GetHashCode() ^ SetID.GetHashCode();
            }
        }

        #region Default ( Empty ) Class Constuctor
        /// <summary>
        /// default constructor
        /// </summary>
        public AdvertisementSet()
        {

        }

        public AdvertisementSet(DomainObjectID id)
        {
            base.id = id;


        }
        #endregion // End of Default ( Empty ) Class Constuctor
        
        #region Public Properties

        public virtual decimal AdCPC
        {
            get { return _adCPC; }
            set { _isChanged |= (_adCPC != value); _adCPC = value; }
        }

        
        /// <summary>
        /// Returns whether or not the object has changed it's values.
        /// </summary>
        public virtual bool IsChanged
        {
            get { return _isChanged; }
        }
        
        /// <summary>
        /// Returns whether or not the object has changed it's values.
        /// </summary>
        public virtual bool IsDeleted
        {
            get { return _isDeleted; }
        }
        
        #endregion 
        
        #region Public Functions
        
        /// <summary>
        /// mark the item as deleted
        /// </summary>
        public virtual void MarkAsDeleted()
        {
            _isDeleted = true;
            _isChanged = true;
        }
        
        
        #endregion
        
        #region Equals And HashCode Overrides
        /// <summary>
        /// local implementation of Equals based on unique value members
        /// </summary>
        public override bool Equals( object obj )
        {
            if( this == obj ) return true;
            if( ( obj == null ) || ( obj.GetType() != this.GetType() ) ) return false;
            AdvertisementStatus castObj = (AdvertisementStatus)obj; 
            return ID.Equals(castObj.ID);
        }
        
        /// <summary>
        /// local implementation of GetHashCode based on unique value members
        /// </summary>
        public override int GetHashCode()
        {
            return ID.GetHashCode();
        }
        #endregion
        
    }



При создании объекта класса AdvertisementSet не происходит сохранения, вываливается такая ошибка:

Castle.Services.Transaction.CommitResourceException: Could not commit transaction, one (or more) of the resources failed ---> NHibernate.StaleStateException: Unexpected row count: 0; expected: 1
   at NHibernate.AdoNet.Expectations.BasicExpectation.VerifyOutcomeNonBatched(Int32 rowCount, IDbCommand statement)
   at NHibernate.Impl.NonBatchingBatcher.AddToBatch(IExpectation expectation)
   at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
   at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, ISessionImplementor session)
   at NHibernate.Impl.ScheduledUpdate.Execute()
   at NHibernate.Impl.SessionImpl.Execute(IExecutable executable)
   at NHibernate.Impl.SessionImpl.ExecuteAll(IList list)
   at NHibernate.Impl.SessionImpl.Execute()
   at NHibernate.Impl.SessionImpl.Flush()
   at NHibernate.Transaction.AdoTransaction.Commit()
   at Castle.Facilities.NHibernateIntegration.Internal.ResourceAdapter.Commit()
   at Castle.Services.Transaction.AbstractTransaction.Commit()
   --- End of inner exception stack trace ---
   at Castle.Services.Transaction.AbstractTransaction.Commit()
   at Castle.Services.Transaction.StandardTransaction.Commit()
   at Castle.Facilities.AutomaticTransactionManagement.TransactionInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at AdvertisementServiceProxy0cfad14704e74e48bfba6200ce955ff4.GenerateNewAdvertisementSet(IList`1 advertisements)


Создаю так:


int maxSetID = GetMaxAdvertisementSet() + 1;

            foreach(Advertisement advertisement in advertisements)
            {
                AdvertisementSet.DomainObjectID id = new AdvertisementSet.DomainObjectID(maxSetID, advertisement);
                AdvertisementSet set = new AdvertisementSet(id);

                set.AdCPC = Convert.ToDecimal(float.IsNaN(advertisement.AdCPC) ? 1 : advertisement.AdCPC);
                
                Session.SaveOrUpdate(set);
            }

            return maxSetID;



Где искать ошибку?
Мудр тот, кто знает не многое, а нужное
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.