I have what's hopefully a simple enough question. If you have a service you want your application to provide, that is not invoked directly by a client, is it worth wrapping in a session bean ?
For example consider that we have a session facade which is what the web tier interacts with directly, they call a method on the facade to pay for their shopping cart or whatever and we then go off and try and create an order, validate their credit card etc. Since the credit card validation code is not being directly invoked by the client, is it still a good candidate for a Session Bean ? i.e. would it be sensible to create a payment bean (statless session bean) which we then invoke locally from the facade. What would be the advantage of doing this rather than just writing a POJO ?
I agree with you. We have developed a complete application with just couple of stateless Session bean just to utilize the container managed transactions. All the business objects are implemented as simple POJO and invoked from the SLSB. Unless you need to maintain the user state or have different transaction requirement for different use cases, i dont think there is any value keeping the overhead of extra home/remote interfaces and dd xml files.
I think this is right, the only reason I could think of for having an EJB is that in future it would allow the system to be scaled as the EJB could be located remotely.
I've another question maybe you can help with - what do you think of using a Session Facade as like a factory for other session beans. For example supposing I have a remote interface for my facade that looks like this :
We can imagine that ShoppingCart is a stateful EJB, the client would call facade.getShoppingCart(); They would not have access to the remote home itnerface (indeed could we not create a remote home??) so that the only way to get a reference to the shopping cart is via the facade.
I see the arguments in favour of this approach as :
1) The ShoppingCart must be a remote object, it it were a Value Object simply calling add(item) would have no effect on the server.
2) The lifecycle of the cart can be managed by the facade, e.g. when we remove the facade the facade can remove the shopping cart meaning the client doesn't have to worry about it.
What do you think of this ? I'm looking for examples where this approach has been followed.
My reply based on what i understand from your statements is as follow.
If you want expose your business methods to a remote client then just use Facade Pattern. What you state is just a factory pattern not Facade. Either you use remote home interface to create your stateful session bean or a factory bean , the resulting issues will be the same. Following are few problems that would kick in using this technique.
1 - Tight coupling, which leads to direct dependence between clients and business objects;
2- Too many method invocations between client and server, leading to network performance problems;
3- Lack of a uniform client access strategy, exposing business objects to misuse.
Instead of accessing remote ejbs via getShopCart() and getCustomer() you should use a remote interface for the actual business usecase Like addIteminCustomerCart() and encapsulate the detail working with ShoppingCart and Customer inside this method of your facade session bean.
That makes sense. The trouble I'm having (as you can maybe tell from the original post) is that if we don't implement the shopping cart as a stateful session bean then we hardly need any EJBs at all apart from the facade.
For example - consider a simple shop where clients search for products, they then add the products to a cart and then pay for the cart and create an order. Boilerplate EJB stuff really. I'm happy that a facade could have methods like addItemToCart(Item) and payForCart(CreditCard). this is fine. For a complex search though we want to use the value list handler so our client can control the number of objects he receives. This would require another stateful bean to act as the value list handler e.g.
SearchProcessor s = facade.getSearchProcessor();
s.getItems(10); // get the next 10 items.
The alternative is to say :
facade.executeSearch(criteria); // this creates a value list handler internally as a POJO
Does that make sense ? Which do you think is best ?
Second approach is better. But the question what i like to ask is whats your objective? Do you want to avoid using EJBs except ur facade bean? Or you just dont want to use Stateful Session Bean? Look u can implement list handler even without using stateful session bean .. thats not a prblem .. but if you have an EJB container then u should use EJB where it can save extra effort.
We have an EJB container, and I've no problem with using EJBs. I'm jsut thinking out loud really. As for the value list handler - we'll need to use this to limit the amount of data passed between the application tier and the web tier. I guess my concern was that the facade is becoming rather fat, it handles searching, adding stuff to the cart and creating orders. This is the only interface that the web tier communicates with. So in the end without setting to have a design that doesn't use EJB, it would appear that I only need the one, since the value list handler is just a POJO accessed via a stateful session facade and the shopping cart is just a list, again stored as member variable of the facade, as is the customer etc. This situation was the motivation for my original question, which is for creating the payment, should I have an itermediate EJB which handles the steps involved in persisting order details, validating credit cards and dispatching emails. This EJB would have no external clients so that was why I was wondering if there was any point in even having one. Problem being, this leaves exactly one bean - my facade!
If there is a chance that your payment procedure takes longer than what one would prefer from a request/reply, you might want to consider handling that asynchronous.
One way of doing that would be to add a asynchronous method to your EJB (if you are using EJB 3.1), otherwise you could use a MDB for the same thing.
Either way, the asynchronous handler would just update some state and thereby reporting back once there is something to report.
The benefit of keeping it all in the EJB layer would be that you would be able to rely on the containers services such as transaction handling and also move into a clustered environment without too much consideration of concurrency issues.
Thanks for that - yes, I'll have an MDB for sending the email, thus if the SMTP server is down etc the users browser wont time out.