Skip to main content

EJB3 Observer pattern

13 replies [Last post]
Anonymous

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 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 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

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Witold Szczerba

Your proposition about using scripting language inspired me, but I did
not use scripting language, but I just refactored my module a little
bit. The first big change was to modify my LoanInspectorBean, now it
has only local interface and it does not include document/task
generators, so it is really much more compact. The second change in
this bean is that now, it's method returns collection of
LoanInspectorReport objects that represents the state of every loan
my bean was processing: loanId, old status, new status,
isStatusChanged method and info about first unpaid installment.
The third thing was what were you talking about, but it is a regular
session bean in Java (not JavaScript). It looks like this:

public class CheckLoansBean implements CheckLoansRemote {
@EJB private LoanInspectorLocal loanInspectorBean;
@EJB private ActionServiceLocal delayedLoanActionServiceBean;
@EJB private SoftActionsGeneratorLocal actionGenerate;
@EJB private DocsActionsGeneratorLocal docsActionGenerate;
private final Logger logger =
Logger.getLogger(CheckLoansBean.class.getName());

public void execute(Date date) {

logger.info("CheckLoansBean: ENTERING... date=" + date);
Collection report =
loanInspectorBean.checkLoans(date);

logger.info("CheckLoansBean: removeExcessiveActions");
delayedLoanActionServiceBean.removeExcessiveActions();

logger.info("CheckLoansBean: generateActions...");
actionGenerate.generate(report);

logger.info("CheckLoansBean: generate PZK actions...");
docsActionGenerate.generatePZK(report);

logger.info("CheckLoansBean: EXITING...");
}
}

And last thing was to "learn" action's and document action's generator
beans to deal with my collection of LoanInspectorReport. This is now
up to them what are they going to do with my report. I really do not
care as long as "report" is good enough for them.

So now, everything that is connecting my 4 beans is my "report" class
and this particular CheckLoans implementation, that can be easily
swapped with something else. Its interface is really not related to
how it works (just one "execute" method), so in the future, when our
application will be working in different companies, we will be able to
move implementation away from interface and combine different
implementations for every customer.

Witold Szczerba

2008/2/21, glassfish@javadesktop.org :
> So, I will offer a 3rd solution to you for you to consider.
> One word: JavaScript.
> (or any scripting language, frankly...)
> Rather than using JBI and XML to represent your processes, use JavaScript.
>
> It's pretty painless to start with, and you can learn the ins and outs of using it better via the documentation.
>
> So, what you have is a ScriptingBean which has a method (lets call in "run") that takes a reference to a blob of Javascript (internal DB reference, a file name, simply a String filled with Javascript, whichever).
>
> Your "run" method prepopulates the Java script context with references to your other service SessionBeans, and it can even inject your Loan Application object.
>
> your Javascript can literally be (this should look very familiar):
> [code]
> var scheduleGenerator = new ScheduleGenerator(loan);
> var schedule = scheduleGenerator.getResult();
>
>
> loanDao.persistSchedule(loan, schedule);
>
> if (loan.getProposal().isRestructuring()) {
>
> loanService.loanRestructActivation(loan);
>
> }
> documentsService.groupGenerateActivationDocuments(loan);
> loan.setLoanStatus(em.getReference(DictLoanStatus.class,
> DictLoanStatus.ACTIVE));
> loan.setStatusChangeDate(new Date());
>
> actionService.genereteOrUpdateBeforeEndAction(loan, schedule);
>
> [/code]
>
> The benefit is simply that you can expose the javascript to end users, you can write a simple interface that generates the Javascript on the fly (if you like, for example, you can simply have a list of processes in a table, and a user could put them together how they like with your generator doing the detail work), etc. However the Javascript is created, you evaluate it dynamically, at run time.
>
> Even in its most crude form, for simple scripts like this, whatever overhead incurred by Javascript is lost in the overall backend processing taking place.
>
> Change it on the fly, no deploys, no restarts, just run it again. Works like a dream.
>
> Give it a look, you can get a script running in your code probably in less than a 1/2 hour.
>
> We use JS everywhere for all sorts of things.
>
> Give that a look, may do the trick for you.
>
> [Message sent by forum member 'whartung' (whartung)]
>
>
> http://forums.java.net/jive/thread.jspa?messageID=260068
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

whartung
Offline
Joined: 2003-06-13

Very good, that's great to hear you've got some solution that works for you.

As I'm sure you realized, a lot of these patterns are pretty simple to pull off. While we may look to things like the container to already handle these things for us, or something larger like JBI, may times just rolling out something quick and specific to the task is more than enough to get the job done and move forward.

The key is simply keeping the abstractions in mind and staying as close to them as practical. Later, even if the underlying technologies change, the abstractions very likely remain the same, so there's little conversion cost later if you do indeed come up with a new need or a better solution in the future.

whartung
Offline
Joined: 2003-06-13

Have you considered looking at the JBI facilities within GF? Because that's essentially what you're talking about, and JBI will do what you want.

Simply, you set up a BPEL script (which is an XML artifact) to lay out your processes, and the JBI engine uses that script to move internal messages around through interested Session Beans. It will do this using a single transaction, and can use the local calling semantics for internal Session Beans.

In the end, you use the BPEL designer tools in NetBeans to maintain the XML file, so that keeps this kind of orchestration away from actual Java code.

It might suit your needs, or at least be a platform to better explore what you may want without having to invent any new wheels on your own.

Witold Szczerba

Hi there,
JBI was actually my secound though after my JMS plan failed. I must
admit, I just looked at it very briefly and, I don't know why, I
thought JBI was designed to be an integration part for different
applications in different environments (using XML/Web Services), not
as a internal orchestrator...
Right now I am going to look at it once again. If what you said about
JBI, being the kind of thing I need and looking for, I will be really
happy :)

Regards,
Witold Szczerba

2008/2/19, glassfish@javadesktop.org :
> Have you considered looking at the JBI facilities within GF? Because that's essentially what you're talking about, and JBI will do what you want.
>
> Simply, you set up a BPEL script (which is an XML artifact) to lay out your processes, and the JBI engine uses that script to move internal messages around through interested Session Beans. It will do this using a single transaction, and can use the local calling semantics for internal Session Beans.
>
> In the end, you use the BPEL designer tools in NetBeans to maintain the XML file, so that keeps this kind of orchestration away from actual Java code.
>
> It might suit your needs, or at least be a platform to better explore what you may want without having to invent any new wheels on your own.
> [Message sent by forum member 'whartung' (whartung)]
>
> http://forums.java.net/jive/thread.jspa?messageID=259720
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

whartung
Offline
Joined: 2003-06-13

Yea, it's certainly positioned after Web Services, but one of the nice things about the GF implementation is that Session Beans are first class citizens and can be called directly by JBI vs through a web service.

This is one of the benefits of being integrated within the container vs an external service.

Witold Szczerba

I was looking everywhere. There is not a single word about how to
invoke EJB3 stateless session bean using @Local interface instead of
serializing/marshaling the message into WSDL WebService or how to
start a process from within session bean, again - without WSDL.
For example here:
https://open-esb.dev.java.net/kb/preview3/ep-javaee-se.html

--first case: Java EE Service Engine As a Service Provider
invoking EJB SLSB via WSDL endpoint from within JBI

--second one: Java EE Service Engine As a Service Consumer
cite: "In this case, the Java EE Service Engine normalizes the SOAP
message that otherwise would have been used in the JAX-WS
communication and sends it to the NMR."

--and of course an example, where JAX-WS (EJB3) is using JMS to get into NMR.

I installed all SOA plugins into NetBeans and I was clicking
everywhere, I was looking for examples and nothing - SOAP, WSDL,
JAX-WS everywhere around! I am loosing hope that JBI can be used to
manage my business process by invoking session beans using @Local
interface passing here and there my plain java objects as method
parameters (read one of my previous post in this thread where I am
talking about the LoanInspectorBean example in my app, to see why I
really do not want my messages to be serialized/marshaled).

Thanks in advance for any help,
Witold Szczerba

2008/2/20, glassfish@javadesktop.org :
> Yea, it's certainly positioned after Web Services, but one of the nice things about the GF implementation is that Session Beans are first class citizens and can be called directly by JBI vs through a web service.
>
> This is one of the benefits of being integrated within the container vs an external service.
>
> [Message sent by forum member 'whartung' (whartung)]
>
>
> http://forums.java.net/jive/thread.jspa?messageID=259790
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

whartung
Offline
Joined: 2003-06-13

Yea, I see what you mean. Bother.

I once had the opportunity to talk with the JBI developers a bit ago, and they said that they had this capability. Perhaps they punted on it. And I do appreciate the desire to avoid serializing the form.

So, I will offer a 3rd solution to you for you to consider.

One word: JavaScript.

(or any scripting language, frankly...)

It comes with Java 6 already, or you can get it here:
http://www.mozilla.org/rhino/

Rather than using JBI and XML to represent your processes, use JavaScript.

It's pretty painless to start with, and you can learn the ins and outs of using it better via the documentation.

So, what you have is a ScriptingBean which has a method (lets call in "run") that takes a reference to a blob of Javascript (internal DB reference, a file name, simply a String filled with Javascript, whichever).

Your "run" method prepopulates the Java script context with references to your other service SessionBeans, and it can even inject your Loan Application object.

your Javascript can literally be (this should look very familiar):
[code]
var scheduleGenerator = new ScheduleGenerator(loan);
var schedule = scheduleGenerator.getResult();

loanDao.persistSchedule(loan, schedule);

if (loan.getProposal().isRestructuring()) {
loanService.loanRestructActivation(loan);
}
documentsService.groupGenerateActivationDocuments(loan);
loan.setLoanStatus(em.getReference(DictLoanStatus.class,
DictLoanStatus.ACTIVE));
loan.setStatusChangeDate(new Date());

actionService.genereteOrUpdateBeforeEndAction(loan, schedule);
[/code]

The benefit is simply that you can expose the javascript to end users, you can write a simple interface that generates the Javascript on the fly (if you like, for example, you can simply have a list of processes in a table, and a user could put them together how they like with your generator doing the detail work), etc. However the Javascript is created, you evaluate it dynamically, at run time.

Even in its most crude form, for simple scripts like this, whatever overhead incurred by Javascript is lost in the overall backend processing taking place.

Change it on the fly, no deploys, no restarts, just run it again. Works like a dream.

Give it a look, you can get a script running in your code probably in less than a 1/2 hour.

We use JS everywhere for all sorts of things.

Give that a look, may do the trick for you.

Witold Szczerba

Well, sounds interesting, will try that :) We use Java6 on the client
side (Swing) and on the server side - you are right, JavaScript is
just here, no extra libraries needed.

I think we could get a little bit off topic, so to make a try to get
on the road again, I would like to suggest one think, a request of
enhancement for @EJB annotation processor in EJB3 environment. What if
we could use it like this:

@EJB Collection someServices;
(of course, because of type erasure, we would have to provide
SomeService.class as parameter somewhere, maybe inside @EJB
annotation).

That would make container to inject every session bean implementing
particular interface into our collection. Of course that would be nice
if we could use List instead of collection and we could be able to
specify some kind of ordering inside our services, but for now - that
would be a huge improvement of EJB spec. Right now I, when I need
something like this I just put the logic into POJOs and use:

ServiceLoader txProcessorLoader =
ServiceLoader.load(TxProcessor.class);

If we would have @EJB for collections annotation, we could easily
invoke every session bean implementing our specific interface to do
some kind of work, instead of using POJOs and injecting services
manually into them.

I know this couples TxProcessor implementations with my TxExecutor,
but sometimes it is just OK... and... by the way...
Observer/Observator pattern define common interface for both as well.

Witold Szczerba

2008/2/21, glassfish@javadesktop.org :
> Yea, I see what you mean. Bother.
>
> I once had the opportunity to talk with the JBI developers a bit ago, and they said that they had this capability. Perhaps they punted on it. And I do appreciate the desire to avoid serializing the form.
>
> So, I will offer a 3rd solution to you for you to consider.
>
> One word: JavaScript.
>
> (or any scripting language, frankly...)
>
> It comes with Java 6 already, or you can get it here:
> http://www.mozilla.org/rhino/
>
> Rather than using JBI and XML to represent your processes, use JavaScript.
>
> It's pretty painless to start with, and you can learn the ins and outs of using it better via the documentation.
>
> So, what you have is a ScriptingBean which has a method (lets call in "run") that takes a reference to a blob of Javascript (internal DB reference, a file name, simply a String filled with Javascript, whichever).
>
> Your "run" method prepopulates the Java script context with references to your other service SessionBeans, and it can even inject your Loan Application object.
>
> your Javascript can literally be (this should look very familiar):
> [code]
> var scheduleGenerator = new ScheduleGenerator(loan);
> var schedule = scheduleGenerator.getResult();
>
>
> loanDao.persistSchedule(loan, schedule);
>
> if (loan.getProposal().isRestructuring()) {
>
> loanService.loanRestructActivation(loan);
>
> }
> documentsService.groupGenerateActivationDocuments(loan);
> loan.setLoanStatus(em.getReference(DictLoanStatus.class,
> DictLoanStatus.ACTIVE));
> loan.setStatusChangeDate(new Date());
>
> actionService.genereteOrUpdateBeforeEndAction(loan, schedule);
>
> [/code]
>
> The benefit is simply that you can expose the javascript to end users, you can write a simple interface that generates the Javascript on the fly (if you like, for example, you can simply have a list of processes in a table, and a user could put them together how they like with your generator doing the detail work), etc. However the Javascript is created, you evaluate it dynamically, at run time.
>
> Even in its most crude form, for simple scripts like this, whatever overhead incurred by Javascript is lost in the overall backend processing taking place.
>
> Change it on the fly, no deploys, no restarts, just run it again. Works like a dream.
>
> Give it a look, you can get a script running in your code probably in less than a 1/2 hour.
>
> We use JS everywhere for all sorts of things.
>
> Give that a look, may do the trick for you.
>
> [Message sent by forum member 'whartung' (whartung)]
>
>
> http://forums.java.net/jive/thread.jspa?messageID=260068
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

ljnelson
Offline
Joined: 2003-08-04

Hi, Witold; I have not yet done the kind of thing you're talking about, but I am thinking about it almost constantly. :-)

My "in my head" solution is/was going to be as follows:

  1. Write one parameterized Interceptor that can be configured to post a JMS message to a queue somewhere when a method completes (the JEE equivalent of firing a loadActivationEvent to a series of LoanActivationListeners in your case).
  2. Write each "observer" to be a JMS subscriber or message-driven bean that you hook up to that queue.

I realize this is very high level--does that give you an idea on one way to proceed? Are there others out there who have tried this approach and found it either lacking or serviceable?

Best,

Laird

Witold Szczerba

Hi there,
my first though about how to improve my application was a JMS way. I
wanted to make it like this:

my Observable, when it has something that might be interesting for
others - it publishes it using JMS. Observers, in that case are MDBs
and they can do whatever they want with a message. Looks like an ideal
solution, easy to introduce, easy and straightforward to implement, no
boilerplate code, just publisher and subscribers invoked automatically
by JMS infrastructure when messages are available.There is but two
huge problems with this approach:

1) message driven beans are operating in its own context.They don't
continue publisher's transactions and they know nothing about
publisher's context, so for example, if that MDB throw an exception, I
will not be able to roll back changes made by my initial Observable. I
do not want my loan to be activated successfully with no documents
attached to it only because there was some problem with document
generator. I want to have loan activated with documents and everything
else or nothing. This is something JMS will not provide.

2) JMS is prepared to work in inter-JVM environment which means it
will serialize/deserialize messages, so I cannot pass just a pointers.
This is often not an issue, but I have a case like this: there is
LoanInspectorBean that is to be invoked once a day. It has to check
few thousands or sometimes few dozen thousands loans to see if each of
them should change status (was:Active, is:Late or was:Late, is:
Terminated). Moreover, this service is supposed to generate some
transactions if, for example, the loan can be the subject for
extinction or whatever. There are few services that might be
interested in the information I am processing in my LoanInspectorBean.
If I would use JMS to notify my observers, my extra uber huge message
would be serialized and send to them, they would have to de-serialize
it and process, which introduces waste of lot of CPU/memory resources.
And again (see no1) I do not want to allow few observers to accomplish
their task while others might failed.

So, this is how my initial idea about JMS died :(
There must be some other way to make EJB3 services easy to decouple...
or maybe not :/
What intrigue me the most is I did not see anything like this in
Spring examples. If Spring could provide some great solution and if
I'd manage to integrate it with my application easily, I could use
Spring beans for observers job.

Regards,
Witold Szczerba

2008/2/19, glassfish@javadesktop.org :
>

Hi, Witold; I have not yet done the kind of thing you're talking about, but I am thinking about it almost constantly. :-)

>
>

My "in my head" solution is/was going to be as follows:
>
>

    >
  1. Write one parameterized Interceptor that can be configured to post a JMS message to a queue somewhere when a method completes (the JEE equivalent of firing a loadActivationEvent to a series of LoanActivationListeners in your case).
  2. >

  3. Write each "observer" to be a JMS subscriber or message-driven bean that you hook up to that queue.
  4. >

>
>

I realize this is very high level--does that give you an idea on one way to proceed? Are there others out there who have tried this approach and found it either lacking or serviceable?

>
>

Best,

> Laird

> [Message sent by forum member 'ljnelson' (ljnelson)]
>
> http://forums.java.net/jive/thread.jspa?messageID=259580
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

ljnelson
Offline
Joined: 2003-08-04

message driven beans are operating in its own
context.They don't
continue publisher's transactions and they know
nothing about
publisher's context

Wow; I did not know this. Are you quite sure? Section 5.4.12 of the EJB 3.0 specification makes no mention of this, and section 13.2.2 says:

13.2.2 Messages Sent or Received Over JMS Sessions and Update of Multiple Databases

The Enterprise JavaBeans architecture makes it possible for an application program to send messages to
or receive messages from one or more JMS Destinations and/or to update data in one or more databases
in a single transaction.

In the following figure, a client invokes the enterprise bean X. Bean X sends a message to a JMS queue
A and updates data in a database B using connections that the Deployer configured to connect with a
JMS provider and a database. Then X calls another enterprise bean, Y. Bean Y updates data in database
C. The EJB server ensures that the operations on A, B, and C are either all committed, or all rolled
back.

(Now obviously this doesn't say what A is doing, which is the whole point of what we're talking about.)

Having said that I am in no position to doubt you as the interaction between MDBs and EJBs is a hole in my knowledge here.

Best,

Laird

whartung
Offline
Joined: 2003-06-13

The problem is that submitting a message to the JMS queue IS the transaction, not the processing of the message. So you can consume JMS messages, from several queues, update several databases, and creates new JMS messages, all in a single transaction, but the actual processing of those message that you transmitted are outside the scope of your transaction.

Witold Szczerba

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
:
> 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 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 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
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net