Question

Duplicated record created on Update in cache

  • 17 January 2024
  • 2 replies
  • 51 views

Userlevel 3
Badge

I'm faced to a behavior in caches that I don't understand.

I created a custom DAC, say MyDAC.

In a graph, I create an instance of this DAC like this :

PXCache myCache = myGraph.Caches[typeOf(MyDAC)];
MyDAC myDacInstance = myCache.Insert();

 
So far, so good : at this moment, myCache contains one record in its inserted collection (I can check it via debug mode in Visual Studio).

Then I modify the properties of the "myDacInstance" object :
myDacInstance.xxx = 10;

Finally, I update the cache with the following instruction :
 myCache.Update(myDacInstance);
 
And then the magic happens: instead of having a single record in myCache, I have two ! Each of course has exactly the same characteristics (even for key properties), so on saving, the system throws an error indicating that there are duplicates. It looks like the Update method fails to recognize that a record having the same key values already exists in cache and create a new record instead of using it.

I checked for key declarations in MyDac and everything seems to be ok. If someone has an idea, it would be appreciated.

Below the code of the DAC I’m using :

using PX.Data;
using PX.Data.BQL;
using PX.Data.ReferentialIntegrity.Attributes;
using PX.Objects.CM;
using PX.Objects.CS;
using PX.Objects.TX;
using System;

namespace Test.DAC
{
    [Serializable()]
    [PXCacheName(PX.Objects.AP.Messages.APTax)]
    public class EAPTax : TaxDetail, IBqlTable
    {
        public static bool IsActive() => PXAccess.FeatureInstalled<FeaturesSetExt.cegEInvoicing>();

        #region Keys
        public class PK : PrimaryKeyOf<EAPTax>.By<tranType, refNbr, lineNbr, taxID>
        {
            public static EAPTax Find(PXGraph graph, String tranType, String refNbr, Int32? lineNbr, String taxID) => FindBy(graph, tranType, refNbr, lineNbr, taxID);
        }
        public static class FK
        {
            public class Document : EAPRegister.PK.ForeignKeyOf<EAPTax>.By<tranType, refNbr> { }
            public class DocumentLine : EAPTran.PK.ForeignKeyOf<EAPTax>.By<tranType, refNbr, lineNbr> { }
            public class CurrencyInfo : PX.Objects.CM.CurrencyInfo.PK.ForeignKeyOf<EAPTax>.By<curyInfoID> { }
            public class Tax : PX.Objects.TX.Tax.PK.ForeignKeyOf<EAPTax>.By<taxID> { }
        }
        #endregion

        #region TranType
        public abstract class tranType : BqlString.Field<tranType> { }

        [PXDBString(3, IsKey = true, IsFixed = true)]
        [PXDBDefault(typeof(EAPRegister.docType))]
        [PXUIField(DisplayName = "Tran. Type", Visibility = PXUIVisibility.Visible, Visible = false)]
        public virtual String TranType { get; set; }
        #endregion

        #region RefNbr
        public abstract class refNbr : BqlString.Field<refNbr> { }
        [PXDBString(15, IsUnicode = true, IsKey = true)]
        [PXDBDefault(typeof(EAPRegister.refNbr))]
        [PXUIField(DisplayName = "Reference Nbr.", Visibility = PXUIVisibility.Visible, Visible = false)]
        public virtual String RefNbr { get; set; }
        #endregion

        #region LineNbr
        public abstract class lineNbr : BqlInt.Field<lineNbr> { }

        [PXDBInt(IsKey = true)]
        [PXDefault()]
        [PXUIField(DisplayName = "Line Nbr.", Visibility = PXUIVisibility.Visible, Visible = false)]
        [PXParent(typeof(Select<EAPRegister, Where<EAPRegister.docType, Equal<Current<tranType>>, And<EAPRegister.refNbr, Equal<Current<refNbr>>>>>))]
        [PXParent(typeof(Select<EAPTran, Where<EAPTran.tranType, Equal<Current<tranType>>, And<EAPTran.refNbr, Equal<Current<refNbr>>, And<EAPTran.lineNbr, Equal<Current<lineNbr>>>>>>))]
        public virtual Int32? LineNbr { get; set; }
        #endregion

        #region TaxID
        public abstract class taxID : BqlString.Field<taxID> { }
        [PXDBString(Tax.taxID.Length, IsUnicode = true, IsKey = true)]
        [PXDefault()]
        [PXUIField(DisplayName = "Tax ID")]
        [PXSelector(typeof(Tax.taxID), DescriptionField = typeof(Tax.descr))]
        public override String TaxID { get; set; }
        #endregion

        #region TaxRate
        public abstract class taxRate : BqlDecimal.Field<taxRate> { }
        #endregion

        #region CuryInfoID
        public abstract class curyInfoID : BqlLong.Field<curyInfoID> { }
        [PXDBLong()]
        [CurrencyInfo(typeof(EAPRegister.curyInfoID))]
        public override Int64? CuryInfoID { get; set; }
        #endregion

        #region CuryOrigTaxableAmt
        public abstract class curyOrigTaxableAmt : BqlDecimal.Field<curyOrigTaxableAmt> { }

        [PXDBCurrency(typeof(curyInfoID), typeof(origTaxableAmt))]
        [PXDefault(TypeCode.Decimal, "0.0")]
        public virtual Decimal? CuryOrigTaxableAmt { get; set; }
        #endregion

        #region OrigTaxableAmt
        public abstract class origTaxableAmt : BqlDecimal.Field<origTaxableAmt> { }

        [PXDBDecimal(4)]
        [PXDefault(TypeCode.Decimal, "0.0")]
        public virtual Decimal? OrigTaxableAmt { get; set; }
        #endregion

        #region CuryTaxableAmt
        public abstract class curyTaxableAmt : BqlDecimal.Field<curyTaxableAmt> { }

        [PXDBCurrency(typeof(curyInfoID), typeof(taxableAmt))]
        [PXDefault(TypeCode.Decimal, "0.0")]
        [PXUIField(DisplayName = "Taxable Amount", Visibility = PXUIVisibility.Visible)]
        public virtual Decimal? CuryTaxableAmt { get; set; }
        #endregion

        #region TaxableAmt
        public abstract class taxableAmt : BqlDecimal.Field<taxableAmt> { }

        [PXDBDecimal(4)]
        [PXDefault(TypeCode.Decimal, "0.0")]
        [PXUIField(DisplayName = "Taxable Amount", Visibility = PXUIVisibility.Visible)]
        public virtual Decimal? TaxableAmt { get; set; }
        #endregion

        #region CuryTaxAmt
        public abstract class curyTaxAmt : BqlDecimal.Field<curyTaxAmt> { }

        [PXDBCurrency(typeof(curyInfoID), typeof(taxAmt))]
        [PXDefault(TypeCode.Decimal, "0.0")]
        [PXUIField(DisplayName = "Tax Amount", Visibility = PXUIVisibility.Visible)]
        public virtual Decimal? CuryTaxAmt { get; set; }

        #endregion

        #region TaxAmt
        public abstract class taxAmt : BqlDecimal.Field<taxAmt> { }

        [PXDBDecimal(4)]
        [PXDefault(TypeCode.Decimal, "0.0")]
        [PXUIField(DisplayName = "Tax Amount", Visibility = PXUIVisibility.Visible)]
        public virtual Decimal? TaxAmt { get; set; }
        #endregion

        #region CuryExpenseAmt
        public abstract class curyExpenseAmt : BqlDecimal.Field<curyExpenseAmt> { }
        [PXDBCurrency(typeof(curyInfoID), typeof(expenseAmt))]
        [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
        [PXUIField(DisplayName = "Expense Amount", Visibility = PXUIVisibility.Visible)]
        public override Decimal? CuryExpenseAmt{ get; set; }
        #endregion

        #region ExpenseAmt
        public abstract class expenseAmt : BqlDecimal.Field<expenseAmt> { }
        #endregion

        #region CuryTaxableDiscountAmt
        public abstract class curyTaxableDiscountAmt : BqlDecimal.Field<curyTaxableDiscountAmt> { }
        [PXDBCurrency(typeof(curyInfoID), typeof(taxableDiscountAmt))]
        [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
        public virtual decimal? CuryTaxableDiscountAmt{get; set;}
        #endregion

        #region TaxableDiscountAmt
        public abstract class taxableDiscountAmt : BqlDecimal.Field<taxableDiscountAmt> { }
        [PXDBDecimal(4)]
        [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
        public virtual decimal? TaxableDiscountAmt { get; set; }
        #endregion

        #region CuryTaxDiscountAmt
        public abstract class curyTaxDiscountAmt : BqlDecimal.Field<curyTaxDiscountAmt> { }
        [PXCurrency(typeof(curyInfoID), typeof(taxDiscountAmt))]
        [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
        public virtual decimal? CuryTaxDiscountAmt { get; set; }
        #endregion

        #region TaxDiscountAmt
        public abstract class taxDiscountAmt : BqlDecimal.Field<taxDiscountAmt> { }
        [PXDecimal(4)]
        [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
        public virtual decimal? TaxDiscountAmt { get; set; }
        #endregion

        #region CuryRetainedTaxableAmt
        public abstract class curyRetainedTaxableAmt : BqlDecimal.Field<curyRetainedTaxableAmt> { }

        [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
        [PXDBCurrency(typeof(curyInfoID), typeof(retainedTaxableAmt))]
        [PXUIField(DisplayName = "Retained Taxable Amount", Visibility = PXUIVisibility.Visible, FieldClass = nameof(FeaturesSet.Retainage))]
        public virtual decimal? CuryRetainedTaxableAmt
        {
            get;
            set;
        }
        #endregion

        #region RetainedTaxableAmt
        public abstract class retainedTaxableAmt : BqlDecimal.Field<retainedTaxableAmt> { }

        [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
        [PXDBDecimal(4)]
        [PXUIField(DisplayName = "Retained Taxable Amount", Visibility = PXUIVisibility.Visible)]
        public virtual decimal? RetainedTaxableAmt
        {
            get;
            set;
        }
        #endregion

        #region CuryRetainedTaxAmt
        public abstract class curyRetainedTaxAmt : BqlDecimal.Field<curyRetainedTaxAmt> { }

        [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
        [PXDBCurrency(typeof(curyInfoID), typeof(retainedTaxAmt))]
        [PXUIField(DisplayName = "Retained Tax", Visibility = PXUIVisibility.Visible, FieldClass = nameof(FeaturesSet.Retainage))]
        public virtual decimal? CuryRetainedTaxAmt
        {
            get;
            set;
        }
        #endregion

        #region RetainedTaxAmt
        public abstract class retainedTaxAmt : BqlDecimal.Field<retainedTaxAmt> { }

        [PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
        [PXDBDecimal(4)]
        [PXUIField(DisplayName = "Retained Tax", Visibility = PXUIVisibility.Visible)]
        public virtual decimal? RetainedTaxAmt
        {
            get;
            set;
        }
        #endregion

        #region tstamp
        public abstract class Tstamp : BqlByteArray.Field<Tstamp> { }

        [PXDBTimestamp()]
        public virtual Byte[] tstamp { get; set; }
        #endregion
    }
}

 


2 replies

Userlevel 3
Badge

Have you tried something like this 

myDacInstance = myCache.Update(myDacInstance);

Userlevel 3
Badge

Hello @vibindas,

You mean use ‘myDacInstance = myCache.Update(myDacInstance);’ instead of ‘myDacInstance = myCache.Insert(myDacInstance);’ ? If so, I've already tried this approach, but it didn't work either.

Thanks in any case for the suggestion.

 

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved