Open Closed

Audit log entity changes for ValueObject #6039


User avatar
0
s4lv0 created
  • ABP Framework version: v7.4.0
  • UI Type: Angular
  • Database System: EF Core (PostgreSQL)

The changes made to the value objects of an aggregate root are not tracked in the 'AbpEntityPropertyChanges' table. If I add the value object to the 'EntityHistorySelector' list, I get an error. 2023-10-23 16:36:46.686 +02:00 [ERR] An error occurred while saving the entity changes. See the inner exception for details. Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details. ---> Npgsql.PostgresException (0x80004005): 23502: null value in column "EntityId" of relation "AbpEntityChanges" violates not-null constraint


5 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can refer to this: https://github.com/abpframework/abp/blob/dev/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs#L368

  • User Avatar
    0
    s4lv0 created

    Hi, the unit test confirm my error: EntityId is null-

    Please add the following check here on the update operation && !x.EntityChanges[1].EntityId.IsNullOrEmpty()

    You will have the following test result:

    Volo.Abp.Auditing.Auditing_Tests.Should_Write_AuditLog_For_ValueObject_Entity Source: Auditing_Tests.cs line 366 Duration: 9,8 sec Message:  NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching: SaveAsync(x => ((((((((((x.EntityChanges.Count == 2) AndAlso (Convert(x.EntityChanges.get_Item(0).ChangeType, Int32) == 1)) AndAlso (x.EntityChanges.get_Item(0).EntityTypeFullName == Volo.Abp.Auditing.App.Entities.AppEntityWithValueObject.FullName)) AndAlso (Convert(x.EntityChanges.get_Item(1).ChangeType, Int32) == 1)) AndAlso (x.EntityChanges.get_Item(1).EntityTypeFullName == Volo.Abp.Auditing.App.Entities.AppEntityWithValueObjectAddress.FullName)) AndAlso (x.EntityChanges.get_Item(1).PropertyChanges.Count == 1)) AndAlso (x.EntityChanges.get_Item(1).PropertyChanges.get_Item(0).PropertyName == "Country")) AndAlso (x.EntityChanges.get_Item(1).PropertyChanges.get_Item(0).OriginalValue == ""England"")) AndAlso (x.EntityChanges.get_Item(1).PropertyChanges.get_Item(0).NewValue == ""Germany"")) AndAlso Not(x.EntityChanges.get_Item(1).EntityId.IsNullOrEmpty()))) Actually received no matching calls. Received 2 non-matching calls (non-matching arguments indicated with '*' characters): SaveAsync(*AUDIT LOG: [---: -------] - UserName - UserId : - - ClientIpAddress : - ExecutionDuration : 332 - Entity Changes: - [Created] Volo.Abp.Auditing.App.Entities.AppEntityWithValueObjectAddress, Id = AppEntityWithValueObjectId: -> "08d140ca-5b9f-4f28-a797-b7d3b77b1522" Country: -> "England" - [Updated] Volo.Abp.Auditing.App.Entities.AppEntityWithValueObject, Id = 08d140ca-5b9f-4f28-a797-b7d3b77b1522 Name: "test name" -> "test name 2" - [Deleted] Volo.Abp.Auditing.App.Entities.AppEntityWithValueObjectAddress, Id = AppEntityWithValueObjectId: "08d140ca-5b9f-4f28-a797-b7d3b77b1522" -> Country: "USA" -> *) SaveAsync(*AUDIT LOG: [---: -------] - UserName - UserId : - - ClientIpAddress : - ExecutionDuration : 59 - Entity Changes: - [Updated] Volo.Abp.Auditing.App.Entities.AppEntityWithValueObject, Id = 08d140ca-5b9f-4f28-a797-b7d3b77b1522 - [Updated] Volo.Abp.Auditing.App.Entities.AppEntityWithValueObjectAddress, Id = Country: "England" -> "Germany" *) Stack Trace:  ReceivedCallsExceptionThrower.Throw(ICallSpecification callSpecification, IEnumerable`1 matchingCalls, IEnumerable`1 nonMatchingCalls, Quantity requiredQuantity) CheckReceivedCallsHandler.Handle(ICall call) Route.Handle(ICall call) CallRouter.Route(ICall call) CastleForwardingInterceptor.Intercept(IInvocation invocation) AbstractInvocation.Proceed() ProxyIdInterceptor.Intercept(IInvocation invocation) AbstractInvocation.Proceed() ObjectProxy.SaveAsync(AuditLogInfo auditInfo) Auditing_Tests.Should_Write_AuditLog_For_ValueObject_Entity() line 412 --- End of stack trace from previous location ---

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Two Entities with the same properties but with different Ids are considered as different entities. However, Value Objects have no Ids and they are considered as equals if they have the same property values. https://docs.abp.io/en/abp/latest/Value-Objects#value-objects

  • User Avatar
    0
    s4lv0 created

    Hi,

    I'm writing to bring your attention to an issue with the auditing process in the Volo.Abp.Auditing module. I've observed that the auditing process does not properly support value objects, and I would like to discuss a specific problem I've encountered.

    Through a test, I've identified that the error in inserting data into the EntityChanges table is due to the fact that the EntityId is null, as evidenced by the test results.

    In summary, I'm raising a concern with the Volo.Abp.Auditing module, as it currently fails to track changes to the properties of value objects. This issue stems from an error in inserting data into the EntityChanges table, which does not allow null values in the EntityId column.

    I would appreciate your guidance on a potential solution to this problem. Your assistance in resolving this issue would be greatly appreciated.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    In summary, I'm raising a concern with the Volo.Abp.Auditing module, as it currently fails to track changes to the properties of value objects. This issue stems from an error in inserting data into the EntityChanges table, which does not allow null values in the EntityId column.

    Yes, this is by design. because the ValueObject has no IDs.

    Anyway, you can change it if you want.

    builder.Entity<EntityChange>(b =>
    {
        b.Property(x => x.EntityId).IsRequired(false);
    });
    

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19