Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OBPIH-5984 Fix lazyInitialization issue when building approval emails #4389

Conversation

drodzewicz
Copy link
Collaborator

In the end, the issue was with LazyInitializationException which occurred when building the approver emails.
The interesting part was that it didn't occur every time and at first, I had trouble reproducing this bug locally.

To be more specific there is a case where we access some values like requisitions.events inside of the GSP templates and extract status and comment from it, and that's the place where the lazyInitializationException is being thrown.
To fix this issue I decided to just fetch the Requisition again in the event handler instead of relying on the requisition passed in the RequisitionStatusTransitionEvent.

Wrapping the method with Requisition.withSession didn't help btw.

Requisition.withSession {
        if (requisition.shouldSendApprovalNotification()) {
            notificationService.publishRequisitionStatusTransitionNotifications(requisition)
        }
}

@@ -18,8 +19,9 @@ class RequisitionStatusTransitionEventService implements ApplicationListener<Req
NotificationService notificationService

void onApplicationEvent(RequisitionStatusTransitionEvent event) {
if (event.requisition.shouldSendApprovalNotification()) {
notificationService.publishRequisitionStatusTransitionNotifications(event.requisition)
Requisition requisition = Requisition.get(event.requisition.id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My conscience wouldn't allow me to leave this without a comment even though we agreed on a similar solution somewhere, so:

  1. If the problem with the LazyInitializationException happens here, it should be enough to add @Transactional annotation for this service
  2. If it happens in the view (which I assume happens), I'd prefer to create a data service method that would eagerly fetch the events using @Join annotation instead of fetching the requisition twice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I agree a comment should be added.
By the way this is grails 1 so @Join services are probably not available to us here

Copy link
Collaborator

@kchelstowski kchelstowski Nov 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drodzewicz

yes, I agree a comment should be added.

I didn't mean to add a comment in the code, I just meant that my conscience wouldn't allow me to leave this PR without the comment 😆

By the way this is grails 1 so @Join services are probably not available to us here

Oh, is it?..... then I apologize, but I'd consider adding a TODO to change it to the data service method I proposed in Grails 3, if everyone agrees on my preposition

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add the TODO for Grails 3

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should always pass the ID rather than the object to these events (see RefreshProductAvailabilityEvent) because there's no guarantee the event handler will be executed synchronously. We should treat them similar to Quartz jobs.

@kchelstowski
Copy link
Collaborator

PS. I'm fine if you all agree on pushing this solution through, just wanted to make sure I mention my personal opinion on that.

@drodzewicz drodzewicz force-pushed the OBPIH-5984-some-approval-emails-not-sent-due-to-null-pointer-exception branch from 8b0ebcc to 171e524 Compare November 24, 2023 10:14
@@ -18,8 +19,9 @@ class RequisitionStatusTransitionEventService implements ApplicationListener<Req
NotificationService notificationService

void onApplicationEvent(RequisitionStatusTransitionEvent event) {
if (event.requisition.shouldSendApprovalNotification()) {
notificationService.publishRequisitionStatusTransitionNotifications(event.requisition)
Requisition requisition = Requisition.get(event.requisition.id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should always pass the ID rather than the object to these events (see RefreshProductAvailabilityEvent) because there's no guarantee the event handler will be executed synchronously. We should treat them similar to Quartz jobs.

@jmiranda
Copy link
Member

Great job on the investigation, @drodzewicz.

@awalkowiak
Copy link
Collaborator

As agreed on the standup this one can be merged

@awalkowiak awalkowiak merged commit 29ab869 into release/0.8.23-hotfix1 Nov 27, 2023
2 checks passed
@awalkowiak awalkowiak deleted the OBPIH-5984-some-approval-emails-not-sent-due-to-null-pointer-exception branch November 27, 2023 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants