Open Closed

OrganizationUnit Update events are not published #7412


User avatar
0
WaelRazouk created
  • ABP Framework version: v8.1.1
  • UI Type: Angular
  • Database System: EF Core (SQL Server)
  • Tiered (for MVC) or Auth Server Separated (for Angular): yes
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

I have the micro-service architecture.

Follow the steps described in https://docs.abp.io/en/abp/latest/Distributed-Event-Bus#entity-synchronizer and try to synchronize OrganizationUnit (so I can have a replica of the table in my custom service)

Here is the synchronizer class


public class CssDepartmentSynchronizer :
    EntitySynchronizer<CssDepartment, OrganizationUnitEto>
{

    private readonly ILogger<CssDepartmentSynchronizer> _logger;

    public CssDepartmentSynchronizer(
        IObjectMapper objectMapper, 
        IRepository<CssDepartment> repository,
        ILogger<CssDepartmentSynchronizer> logger) : base(objectMapper, repository)
    {
        _logger = logger;
    }

    public override Task HandleEventAsync(EntityCreatedEto<OrganizationUnitEto> eventData)
    {
        _logger.LogInformation("CssDepartmentSynchronizer EntityCreatedEto");
        return base.HandleEventAsync(eventData);
    }

    public override Task HandleEventAsync(EntityDeletedEto<OrganizationUnitEto> eventData)
    {
        _logger.LogInformation("CssDepartmentSynchronizer EntityDeletedEto");
        return base.HandleEventAsync(eventData);
    }

    public override Task HandleEventAsync(EntityUpdatedEto<OrganizationUnitEto> eventData)
    {
        _logger.LogInformation("CssDepartmentSynchronizer EntityUpdatedEto");
        return base.HandleEventAsync(eventData);
    }

    protected override async Task<CssDepartment?> FindLocalEntityAsync(OrganizationUnitEto eto)
    {
        _logger.LogInformation("CssDepartmentSynchronizer FindLocalEntityAsync");
        var entity = await Repository.FindAsync(d => d.Id  == eto.Id);
        if (entity == null)
            _logger.LogInformation("CssDepartmentSynchronizer not found");
        else
            _logger.LogInformation("CssDepartmentSynchronizer found");
        return entity;
    }
}

This class is not being hit (no logs added to the logs file). Similar code for IdentityUser works fine

public class CssUserSynchronizer :
 EntitySynchronizer<CssUser, UserEto>

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

    Hi,

    Did you configure the AutoEventSelectors

    Configure<AbpDistributedEntityEventOptions>(options =>
    {
        options.AutoEventSelectors.Add<OrganizationUnit>();
        options.EtoMappings.Add<OrganizationUnit, OrganizationUnitEto>();
    });
    
  • User Avatar
    0
    WaelRazouk created

    Hi,

    Did you configure the AutoEventSelectors

    Configure<AbpDistributedEntityEventOptions>(options => 
    { 
        options.AutoEventSelectors.Add<OrganizationUnit>(); 
        options.EtoMappings.Add<OrganizationUnit, OrganizationUnitEto>(); 
    }); 
    

    Hi, yes in my DomainModule, here is the ConfigureServices method

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        base.ConfigureServices(context);
        Configure<AbpDistributedEntityEventOptions>(options =>
        {
            options.AutoEventSelectors.Add<OrganizationUnit>();
            options.EtoMappings.Add<OrganizationUnit, OrganizationUnitEto>();
        });
    }
    
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    I will check it

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    It works for me

    My steps:

    • Create a ms template via suite
    • Configure AbpDistributedEntityEventOptions in the IdentityServiceDomainModule
    Configure<AbpDistributedEntityEventOptions>(options =>
    {
        options.AutoEventSelectors.Add<OrganizationUnit>();
        options.EtoMappings.Add<OrganizationUnit, OrganizationUnitEto>();
    });
    
    • Add CssDepartmentSynchronizer to ProductService
    public class CssDepartmentSynchronizer :
        EntitySynchronizer<Product, OrganizationUnitEto>
    {
    
        private readonly ILogger<CssDepartmentSynchronizer> _logger;
    
        public CssDepartmentSynchronizer(
            IObjectMapper objectMapper, 
            IRepository<Product> repository,
            ILogger<CssDepartmentSynchronizer> logger) : base(objectMapper, repository)
        {
            _logger = logger;
        }
    
        public override Task HandleEventAsync(EntityCreatedEto<OrganizationUnitEto> eventData)
        {
            _logger.LogInformation("CssDepartmentSynchronizer EntityCreatedEto");
            //return base.HandleEventAsync(eventData);
            return Task.CompletedTask;
        }
    
        public override Task HandleEventAsync(EntityDeletedEto<OrganizationUnitEto> eventData)
        {
            _logger.LogInformation("CssDepartmentSynchronizer EntityDeletedEto");
            //return base.HandleEventAsync(eventData);
            return Task.CompletedTask;
        }
    
        public override Task HandleEventAsync(EntityUpdatedEto<OrganizationUnitEto> eventData)
        {
            _logger.LogInformation("CssDepartmentSynchronizer EntityUpdatedEto");
            //return base.HandleEventAsync(eventData);
            return Task.CompletedTask;
        }
    
        protected override async Task<Product?> FindLocalEntityAsync(OrganizationUnitEto eto)
        {
            _logger.LogInformation("CssDepartmentSynchronizer FindLocalEntityAsync");
            var entity = await Repository.FindAsync(d => d.Id  == eto.Id);
            if (entity == null)
                _logger.LogInformation("CssDepartmentSynchronizer not found");
            else
                _logger.LogInformation("CssDepartmentSynchronizer found");
            return entity;
        }
    }
    

  • User Avatar
    0
    WaelRazouk created

    Hi, It works now (because I moved the AbpDistributedEntityEventOptions to the IdentityServiceDomainModule project ( I was setting it in my service domain project previously.

    But I still have an issue: OrganizationUnitEto doesn't have ParentId property like OrganizationUnit and I need to know this property to save it in my db table. When I try to get the OrganizationUnit entity using IOrganizationUnitRepository I get the following error: [ERR] An error occurred using the connection to database '' on server ''.

    Stacktrace: 2024-07-01 11:00:47.184 +03:00 [ERR] An error occurred using the connection to database '' on server ''. 2024-07-01 11:00:47.192 +03:00 [ERR] An exception occurred while iterating over the results of a query for context type 'RMG.Iso20.IdentityService.EntityFrameworkCore.IdentityServiceDbContext'. System.InvalidOperationException: The ConnectionString property has not been initialized. at Microsoft.Data.SqlClient.SqlConnection.PermissionDemand() at Microsoft.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection) at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions) at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource1 retry, SqlConnectionOverrides overrides) at Microsoft.Data.SqlClient.SqlConnection.InternalOpenAsync(CancellationToken cancellationToken) --- End of stack trace from previous location --- at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.MoveNextAsync() System.InvalidOperationException: The ConnectionString property has not been initialized. at Microsoft.Data.SqlClient.SqlConnection.PermissionDemand() at Microsoft.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection) at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions) at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource1 retry, SqlConnectionOverrides overrides) at Microsoft.Data.SqlClient.SqlConnection.InternalOpenAsync(CancellationToken cancellationToken) --- End of stack trace from previous location --- at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.MoveNextAsync()

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can add your MyOrganizationUnitEto to override the OrganizationUnitEto.

    public class MyOrganizationUnitEto
    {
        public Guid? ParentId { get; set}
        ....
        
    }
    
    ....
    
    CreateMap<OrganizationUnit, MyOrganizationUnitEto>();
    ....
    
    Configure<AbpDistributedEntityEventOptions>(options =>
    {
        options.AutoEventSelectors.Add<OrganizationUnit>();
        options.EtoMappings.RemoveAll(x => x.Value.EtoType == typeof(OrganizationUnitEto);
        options.EtoMappings.Add<OrganizationUnit, MyOrganizationUnitEto>(typeof(AbpIdentityDomainModule));
    });
    

    I will add the ParentId to OrganizationUnitEto in the next version https://github.com/abpframework/abp/issues/20136

  • User Avatar
    0
    WaelRazouk created

    Can you confirm where did you add this code?

    Configure<AbpDistributedEntityEventOptions>(options =>
    {
        options.AutoEventSelectors.Add<OrganizationUnit>();
        options.EtoMappings.RemoveAll(x => x.Value.EtoType == typeof(OrganizationUnitEto));
        options.EtoMappings.Add<OrganizationUnit, CustomOrganizationUnitEto>(typeof(AbpIdentityDomainModule));
    });
    

    In which project and service. Because for me It only worked under IdentityService And based on this: I need to define new AutoMapper profile in the IdentityService to map this

    CreateMap<OrganizationUnit, MyOrganizationUnitEto>();
    

    Am I right? or did I miss something?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Add to the IdentityServiceDomainModule

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.2.0-preview. Updated on March 20, 2025, 18:00