Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interceptor is not triggered from another EJB method in same EJB

Scenario

2x same Interceptor in same EJB on 2 methods:

...
 @Interceptors(PerformanceAuditor.class)
public Date refreshIfNecessary() {
    // there is also the PerformanceAuditor-Interceptor on this method
    Pair<Date,String> lastImportDate = importDbDAO.findLatestImportLog();

    someContainer.reloadIfNecessary(lastImportDate);
    return lastImportDate.getLeft();
}

@Interceptors(PerformanceAuditor.class)
public boolean checkAndRefreshIfNecessary(final Date importDate) {
    Date lastImportDate = refreshIfNecessary();
    return lastImportDate.after(importDate);
}
...

Now we call on this EJB the methods externally with the following outcome:

  • calling refreshIfNecessary() -> PerformanceAuditor is called 2 times
  • calling checkAndRefreshIfNecessary() -> PerformanceAuditor is called also 2 times! (but expected 3 times since one nesting level more!)

So what's happening here?

like image 904
Strinder Avatar asked Feb 11 '13 10:02

Strinder


1 Answers

The answer is simple:

Interceptors "trigger" only if called as an "EJB call" (i.e. via their EJB interface). But in checkAndRefreshIfNecessary() the call of checkAndRefreshIfNecessary() is a simple Java method call and therefor not noticed by the container.

Solution: To call a method in an EJB internally as EJB call you have to go via its Interface which can be accessed e.g. via injected SessionContext and then via context.getEJBLocalObject()... But this is certainly no a pretty solution! Better rethink your design in such cases!

PS: That's a beautiful example that one has still to understand the internals of an application server. Unfortunately from EJB3 onwards most features are so easy to use that more and more developers will not be confronted with the internals which will lead more often to such errors or at least bad design...

like image 121
Strinder Avatar answered Nov 16 '22 22:11

Strinder