i’ve a question with a sample project i created here: https://github.com/mariodavid/cuba-example-application-events
What i want to achieve is to get a more decoupled business logic architecture through an event system. Therefore i used Spring’s application event system to publish events in the system and catch it in other parts of the system to perform any kind of actions.
Generally speaking, it works very well, but i have some gotchas, where i’m not sure how to resolve them. First of all here’s a brief description of the classes responsible for doing the different parts:
Entities: Order, Customer
Entity Listener: CustomerCreatedEntityListener, OrderCreatedEventListener (turn DB events into application events)
Application Events: CustomerCreatedEvent, OrderCreatedEvent
Application Event Handler: CustomerUserCreator, OrderCreatedLogger
Application Event Producer: ApplicationEventProducerService
Basically i created an event when a customer is created. In the entityListener for Customer i publish a CustomerCreatedEvent that will be catched from the CustomerUserCreator, that will use the customer information to create a corresponding user for this customer in the system (asynchronously). Everything works well here in this scenario, except that in the logs of the application occur the following errors / warnings:
2016-10-02 13:27:41.203 ERROR [http-nio-8080-exec-29/app-core/admin] com.haulmont.cuba.core.sys.ServiceInterceptor - Invoking void com.company.ceae.service.ApplicationEventProducerService.produceApplicationEvent(Object) from another service 2016-10-02 13:27:41.265 WARN [http-nio-8080-exec-29/app-core/admin] com.company.ceae.listener.application.CustomerUserCreator - The customer was created... 2016-10-02 13:27:41.572 WARN [http-nio-8080-exec-29/app-core/admin] com.company.ceae.listener.application.CustomerUserCreator - The user Nay was created... 2016-10-02 13:27:41.572 WARN [http-nio-8080-exec-29/app-core/admin] com.haulmont.cuba.core.sys.ServiceInterceptor - Open transaction left in ApplicationEventProducerService.produceApplicationEvent(..)
Nevertheless, everthing worked out fine -but i’m not really sure what this message (esp. error) is going to tell me.
Next thing i tried is to do the same for Order creation. In this case OrderCreatedEventListener catches the DB event and publishes a OrderCreatedEvent that will be catched from OrderCreatedLogger which will just log the information with the source of event creation. This works as well.
What doesn’t seem to work is, that if i want to publish events from the frontend. In this case i added a postCommit method to the OrderEdit that should additionally publish the OrderCreatedEvent. Unfortunately it will not get picked up from the OrderCreatedLogger. I think the reason is that the other stuff is happening all on the middleware layer, but this one not. But, actually the OrderEdit just calls ApplicationEventProducerService, so the execution of the event creation through Spring is done on the middleware (since ApplicationEventProducerServiceBean is in the core module).
I think i misunderstand something here regarding what can be executed when etc. Actually i don’t think it’s a problem directly related to CUBA, but i thought you might have an opinion on that anyway.
I think using application events are a really cool way of decomposing the application components dependencies structure, so i’d really like to see this working properly.
I would appreciate your help.