users@glassfish.java.net

Re: EJB3 Observer pattern

From: Witold Szczerba <pljosh.mail_at_gmail.com>
Date: Tue, 19 Feb 2008 00:23:32 +0100

Well, after some thoughts I realized this is not going to work :/
There are two problems with my approach:

1) there is no guarantee that server will create my observers before
my observable would like to notify them. If there is SomeServiceBean
implementing Observer and it is not invoked by anyone, it will not be
created and its @PostConstruct method will not be invoked which means
- it will not register itself in Observable bean. Someone would have
to invoke any of its method first, and there is no way to accomplish
that without using vendor specific mechanisms. Quite ugly :/

2) This one is even worse: in my example, I created field with list of
observers in Observable session bean, but there can be plenty
instances of my Observable (stateless' session bean pool). That means,
even if issue no1 could be vanquished, the observers would register
themselves in random instances of Observable or only in one of them.

Now, I really have no idea how to make my EJB3 application better. I
am aware of interceptors, but I do not thing they are the right way
for my issue.
Any help is kindly welcome!

W.Sz.


2008/2/18, Witold Szczerba <pljosh.mail_at_gmail.com>:
> Hi there,
> in my EJB3 application I have lot of session beans like this:
> @Stateless
> public class LoanActivationBean implements LoanActivationLocal {
> ...
> public void execute(Loan loan) {
> ScheduleGenerator scheduleGenerator = new ScheduleGenerator(loan);
> Set<LoanScheduleEntry> schedule = scheduleGenerator.getResult();
>
> loanDao.persistSchedule(loan, schedule);
>
> if (loan.getProposal().isRestructuring()) {
> loanRestructActivation(loan);
> }
> documentsService.groupGenerateActivationDocuments(loan);
> loan.setLoanStatus(em.getReference(DictLoanStatus.class,
> DictLoanStatus.ACTIVE));
> loan.setStatusChangeDate(new Date());
>
> actionService.genereteOrUpdateBeforeEndAction(loan, schedule);
> }
> }
>
> As you can see, when somebody is activating loan there are few steps
> that does need to be accomplished:
> 1) generate schedule and persist it
> 2) check if this is a restructuring loan and if so - invoke additional
> operations
> 3) generate special documents
> 4) change loan status
> 5) do something with action subsystem
>
> Originally, there were only steps: 1,2 and 4, but later, other guys
> had to add their special actions - one to feed document service and
> one for actions/tasks service.
>
> I really don't like the way it looks like now. My loan activation
> service is really not interested in those two other services but their
> code is inside my class. There are many, many other services in our
> application that looks more or less like this.
>
> I was thinking about Observer pattern. My session bean could invoke
> all interested observers that are registered... but the problem is how
> to register those services?
> I was thinking about something like this:
>
> lets add field like List<LoanActivationObserver> observers into my
> LoanActivationService and one method like this:
> public void addObserver(LoanActivationObserver observer) {
> observers.add(observer);
> }
>
> The problem is: how and where other services should register themselves.
> I was thinking about such an idea: let every session bean that would
> like to be notified about newly activated loans create life-cycle,
> post construct method:
>
> @Stateless
> public class SomeServiceBean implements SomeServiceLocal,
> LoanActivationObserver {
>
> @EJB LoanActivationLocal loanActivationBean;
> @Resource SessionContext ctx;
> @PostConstruct initialize() {
> loanActivationBean.addObserver(ctx.getBussinessObject(LoanActivationObserver.class));
> }
> ...other methods including the one from LoanActivationObserver interface...
> }
>
> I am very surprised I couldn't find anything like this on the net
> before, as this looks like a very simple Observer pattern
> implementation in EJB3 environment and this is one of the most
> important pattern to decouple application code.
>
> Is this idea actually correct from EJB3 point of view? Can I be sure
> that @PostConstruct method will be invoked before my
> LoanActivationBean will activate any loan, or maybe EJB3 server is not
> going to create stateless session beans that were not invoked
> explicitly?
> What do you think about all this?
>
> Regards,
> Witold Szczerba
>