Skip to main content
Solved

Duplicated record created on Update in cache


Forum|alt.badge.img+1

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
    }
}

 

Best answer by ygagnaire12

Hi @Chris Hackett ,

In fact, I stopped spending time figuring out what's wrong. I just reorganised my code slightly differently to avoid using insert/update in this case, it's working so far.

View original
Did this topic help you find an answer to your question?

4 replies

Forum|alt.badge.img
  • 70 replies
  • May 3, 2024

Have you tried something like this 

myDacInstance = myCache.Update(myDacInstance);


Forum|alt.badge.img+1
  • Author
  • Varsity II
  • 46 replies
  • May 7, 2024

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.

 


Chris Hackett
Community Manager
Forum|alt.badge.img
  • Acumatica Community Manager
  • 2754 replies
  • July 1, 2024

Hi @ygagnaire12 were you able to find a solution? Thank you!


Forum|alt.badge.img+1
  • Author
  • Varsity II
  • 46 replies
  • Answer
  • July 30, 2024

Hi @Chris Hackett ,

In fact, I stopped spending time figuring out what's wrong. I just reorganised my code slightly differently to avoid using insert/update in this case, it's working so far.


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings