We're in the process of redeveloping a legacy system. Our system reads and writes data to a mainframe-based database. Due to company requirements, we do not access the mainframe directly, but through a Java layer provided to us by another part of the company.
We have completed the first few iterations of our project and are currently re-evaluating some decisions.
So far, we have designed our business entities as Stateful Session Beans. While this is obviously less than ideal, we had several reasons. First, we did not want the container to randomly try to save data to the back end. Second, we would have had very complex Bean managed persistence. Third, our business entity model doesn't map cleanly to the transactions necessary to talk to the back end - often some or all of several entities are required to complete a transaction, and this would require our entities to have knowledge of each other. Note that we are not at liberty to make mainframe changes at this time.
Our solution was to have stateless and stateful Session Beans to handle process control, and stateful session beans referenced by them for managing the data. We do have Data Objects (I think that's what you call them here) that allow us to update most or all of the data on our beans all at once, and allows easy data sending back to the client. (In our current system, data is updated in chunks in most cases).
Now we are considering removing the Session Bean design of our business entities and using straight Java Beans. The reason for this is that we really aren't gaining anything, and, when we can change the transactions and/or go directly to the database, we can go to an entity bean model fairly easily.
I'm curious as to what others think of this idea? Basically our business processes (the stateful beans) would maintain references to the Javabeans instead of to other EJBs. These processes of course can build the transactions we need through the Java layer to the back end. At the same time, we are keeping ourselves open to anticipated (and desired) future changes.
Thanks for your comments.
From what I understand of your architecture,you are probably internet enabling you existing legacy software.Also you said that you are not accessing the database directly,but through the mainframe.If such is the case,then perhaps the stateless session bean model would be an ideal high performance solution to your problem.This certainly would allow you to "gain something",in terms of performance,rapid development and future fexible enhancements.As the EJB container maintains a pool of stateless session beans,which are reused,the performance is high.Note that you cannot have a model of a client talking to a stateless session bean,which in turn talks to a stateful session bean.(This stateful session bean could in turn talk to one or more entity beans).The reasons are obvious, as if there are more than one method invocations,the stateless session bean is likely to forget the previous client state.
I do support your idea of data objects,which manipulate and populate coarse grained objects to improve performance.
So I think you will have to carefully work out your architecture,considering the fact that you might have new entities defined(coz of introdution of new business logic - web enabled application or otherwise).This will mandate changes in the database schema and you will have to make the EJB code completely transparent to the database changes.
To reduce your development efforts,you can use an O/R mapping tool like TopLink.
Also for legacy systems,you will have to think about data translation between your EJB server and mainframes.This is certainly not easy and we had several problems while doing so.We had to implement a proprietry solution for it.However,I would recommend using IBM specific products for forward and backward translations with the mainframe.
Thanks for your reply...sorry for my delay.
Yes, we are internet enabling a legacy system. The problem is, we cannot go directly to the mainframe. To fit into our corporate environment, we must use an intermediate layer. We talk to this layer and it talks to the mainframe (basically sending the copybooks).
Because of this, simply using data mapping is not likely to work.
The solution we are going about now is basically a facade-type pattern as someone discusses later in this thread. This combined with the middle layer mentioned above does allow our EJBs to be basically transparent to database schema changes.
In addition,you can also consider using CORBA to access your legacy code.Steps taken by us include:
1) Develop wrappers around existing legacy code.
2) Using proxy objects to access the existing logic.
Good hearing from you again. A couple of points:
1) With entity beans, you still have some control of the frequency of database reads and updates through transactions. You don't give up total control to the application server.
2) Several business entities are required to complete a transaction - do you mean that a transaction would span several entity beans? In that case, have you considered wrapping those entity beans with a session bean layer, where the session bean performs the transaction and hooks into the appropriate entity beans?
3) Very complex BMP - would you not have a similar problem of writing the persistence logic regardless of whether you used entity beans or not?
4) Data objects work well and are a good alternative to entity beans. The only disadvantages I can see to data objects are:
* No caching support
* No implicit transactions or security
* Non-standard means tougher to ramp up newhires and leverage tools, such as UML-EJB mapping tools
* Stateful session beans cannot be easily pooled and tend to eat up memory
I think this issue, as well as the one on performing validation in "Detail" objects (aka Data Objects), are special cases of a general pattern, the use of a Facade.
We are using Facade to make use of EJBs, legacy APIs, etc. transparent at the Servlet/JSP level. The way it works is basically:
1. Create a JavaBean (class) that implements a transaction or use case. For example "Post a message". The interface of this bean would be all of the required attributes from one or more sources.
2. Have the class implement an "action" method like "execute()" or "invoke():. This can be standardized by having all Facade classes implement a Command interface or similar.
3. The action method can then invoke any validation logic, make use of any EJB session or entity beans, handle all exceptions, and setup any potential return data. In the "Post message" example, this may be a "MessageID" value accessible through a "getMessageID()" method.
4. That's it.
The advantage to this technique is that you can hide all of the messy details about which EJB/API/straight DB calls you might be making, so that this can be easily changed later. It also isolates the presentation layer from messy app server details.
With a bit of planning, you can go from design-level "use cases" to these facade JavaBeans quite readily, and still be able to defer session/stateless session/entity bean decisions until later.
IMHO, the use of EJB at all is dependent on the application or project at hand, and not a "no brainer". Sometimes the implementation of these facade JavaBeans will simply be Java code w/o EJB back-ends. Especially for web applications, this approach is cleaner than embedding EJB calls into Servlets/JSP pages.
We are actually doing something similar, using interfaces rather than classes. All of our entities (And if I am not mistaken, our session beans too) have interfaces aside from those required by EJB. This allows us, as you stated, the flexibility to change our immplementations.
We have already made the decision to use servlets/JSPs talking to a combination of Stateful and Stateless session beans to perform the logic. The only outstanding issue, which we are currently discussing, is the business data objects, and for this we are certainly using a facade-type pattern.
Thanks for your insights.
Hm. One suggestion that maybe totally wrong or just right.
You could also use a session bean (not EJBs) in the JSP/Servlet engine which collects data from the Webpages and then uses a "burst mode" via a Stateless EJB to do the work. This would remove the need for a Stateful EJB.
Furthermore such a session bean provides the developer with a very nice pivot point to work agains.
Just a thought.
Jack's fundamental question - when to stay away from EJB remains unanswered. I think he brings up a good point that at all times, it would not be prudent to adopt an EJB. Ed's argument about standardization is the only argument in favor of an EJB.
Hi Ed, thanks for your insights on this issue. A couple of things:
Regarding your points about control of the entities using transactions, how fine-grained is this control? One problem, as we have come to realize, is that often we have what we're calling Work In Progress (WIP) objects. These WIP objects get updated over one or more calls to the middle tier, then eventually get persisted. Can we totally control when the bean actually tries to write itself? Can we have our entities look like Entity EJBs but not actually do any persistence themselves (and in fact leave it up to a Session bean to do so?) thus allowing us future enhancements?
We have wrapped the entities with a Session Bean layer, as we have to do this anyway, and it is currently the only way to ensure we have all of the data required for a successful transaction to the mainframe.
The reason I mention complex BMP is because if the Entity Beans need to persist (when the container tells them to) and the transactions rely on multiple entity beans, then we cannot ensure that a single entity bean will be sufficient, unless we remodel our entities to look like the transactions. Currently our entity model resembles the business, not the transactions.