I'm pretty new to EJB so I hope someone can help me with this!
I have read a few articles that suggest using a session bean as a facade for accessing entity beans. However, I am unsure as to whether business logic validation should be done in the session bean or the entity bean?
I have a String field in an entity bean that must take one of a set of values that are stored in a database table. This may not always be the case though so I don't want to make the entity bean dependent on this table. If the validation is performed by the session bean, is there any way of preventing direct access to the entity bean by clients?
The idea behind Facade is that the session bean does the validation for the reasons you state. On way to forbid access to the entity bean is through an Access Control List (check with your container vendor for specific implementations). Basically create an internal user and place an ACL on the bean. Then the session bean which is internal passes the internal credentials. This is much like Factory patterns in traditional programming via making the constructors package private.
Internet Applications Division
Adam and Dave,
The issue of where to validate data is coming up far too often. Because we are using EJB does NOT mean we throw away the OO principle of data encapsulation.
By placing data validation in a SB rather than in the EB a number of things go wrong:
1) you have returned to procedural programming since now your EB is not a self-contained object.
2) thus no other SB can simply work with that Entity without having to go through the "controlling" SB, again OO is lost.
3) so now you have doubled the amount of serialization needed, since now you must hop through an intermediary to get the data between the real SB user to the EB. (Remember, all data transferred between beans, even if they are in the same EJB container, must be serialized).
I am eager to read your comments.
Component Base systems are not within themselves OO based. They are implemented using OO paradigms but do not necessarily work in an OO fashion.
The advantages of stripping the business logic out to the sb are actually due to encapsulation but more importantly reuse. For instance yes, I can call the EB without going through the same session bean. I might want that because I dont ALWAYS want to use the exact same business validation rules. For instance imagine an entity bean which sets a balance on an account table. Now we have a bank teller session bean and a credit card teller session bean. They both have very different business rules (one allows negetive balance the other does not) yet now they can both same the same account component. This is not procedural but actually more OO then most "pure" OO implementations. If I had put the business rules in the entity id have to totally rewrite the entity each time for the bank and the client. When in fact, the discrete work done by the account is the same in both cases.
This is not alot different fromt the OO Factory design pattern. The SB becomes an adapter as well as a factory for the SB. We really can apply OO patterns to these component based patterns.
So Ive gained reuse, extensibility, while still maintaining the ability to use OO paradigms to develop. On the subject of serialization thats not true. Containers internally dont need to serialze interbean calls and very very rarely do. Most every container I know of has some very optimized marshalling for inter bean calls.
Internet Applications Division
You touched a very sensible area of EJB development.
First of all, Component Based Systemes are wehat their developers choose them for.
So, while there's no consensus among the experts what Component Based development are.
I think we are pretty safe to say that some developers have this particular requirement that CBD be also object oriented.
Of course there can be non-OO CBD as well like Visual Basic, then some developers will disregard them and others will love them.
But as to what regards the Session Bean facade to Entity Beans you're wrong from an OO point of view as well as from a practical point of view.
You may have other reasons to like that pattern, but for many people the pattern is a clear case of anti-pattern.
1. Session Beans don't have any OO charcateristics, they are procedural goupings of code (as a Pascal Unit if you like) with eventual some state data in case of stateful(Pascal unit also has that).
2. You take business logic out of your AccountEB, than what is left is a plain stupid data capsule. Like C++ struct without any method.
Entity Beans as merely data capsule is another monster anti-pattern that you can see very often these days in some experts' code samples and discussions.
3. On the subject of serialization overhead I'm affraid Justin was absolutely wright.
When an EJBs calls another EJB, the call has to have the same semantics as any other client call to the EJB.
The semantics include:
- interception by Container's Proxy providing concurrency control, transactional control, security control and eventually other app server specific things. Obviously unnecessary overhead in most cases. since database will take care anyway of this issues in ejbLoad() and ejbStore() for entity beans.
- Passing arguments. Common, let's be serious. Maybe your app server generated stubs smart enough to detect calls in the same VM. That's elementary and obvious.
So you can skip serialization for primitive types, and for remote referennces you pass along.
And probably you use an ByteArrayOutputStream for all other objects (or you can still make a few tricks to check for Java supplied immutables like String, Integer and such, but that would be semi-legal), short-cutting the local TCP stack .
But the serialization overhead has to stay.
That's less overhead than a full blown RMI call on TCP stack, but still is a lot of overhead by many people's taste.
I hope you don't pass user defined objects by reference when marshalling same-vm calls, or do you?
So Justin was correct after all in this matter.
1) Session beans show no OO characteristics but are rather a collection of procedural code.
I could not disagree more.
(a) Encapsulation. A method like Teller.transfer() encapsualtes the list of actions in a trandfer.
(b) Polymorphism. This can is show by either method overloading in the simplest terms, or true polymorphism can be handled through the Home/Remote interfaces. This is because you can have a session bean use any remote or home inteface you want. You can now have a multiple types of session beans served by identical home/remote interfaces giving you polymprhic implementations based on the bean name you lookup
(c) Inheritience. Although most component models do not directly support inheritience the underlying implementations can and do, such as remote interface inheritience. Also containers like EAServer which support true IDL inheritence take this a step farther.
With a session bean implementing the three pillars of OO how can you in turn claim they are not an OO concept? And if they dont meet your strictest interpretations so what? Do they serve the business purpose.
2) The idea of representing the model of a system as flat structural data is not IMHO an anti-pattern. If anything, the sillyness of simply encapsulating flat data inside of mostly flat classes is more an anti-pattern that anything. No matter what you have a model of data, and physical object to be modelled and moved. I dont see how an entity bean is more of a bastardization then a DAO class from an API/pattern point of view?
3) Interbean calls still require use of serialization and its associated overhead.
A few points here
(a) Yes the container must still follow the semantics and contract of EJB but no restriction is placed on how the vendor implements it. Although we dont do this in EAServer, some vendors like BEA do indeed pass the objects by reference pointer. It doesnt matter how they implement it, but rather how they expose it. Much as the concrete class can be irrelevant when hidden under an inteface.
(b) You only have the overhead of Java serialization *IF* you pass Java serialized types. I would argue that you can much more effectively pass object data through IDL types including interfaces, enum, struct, union, etc. This would require zero java serialization to marshall, would still meet all the requirements of RMI/IIOP and hence all the requirements of EJB.
(c) As you say you can avoid the overhead of the TCP stack. We do so though using an in-memory implementation of the Socket. In this way we follow all the semantics but marshall through a memory pointer. If you take into account (b) this is very effeciant. As a matter of fact, we never use a single bit of RMI on the wire, as were not required to by the spec. All the spec requires is we use RMI semantics which we do. And we passed the J2EE cts so I assure you it is legal and compliant.
(d) the use of pooled instances like entities and session beans even with the overhead of inter-bean communication still beats the use of standard java classes due to the significant overhead of object construction and GC threading. Id be glad to sit with you and show you benchmarks we have done to prove this.
So if you do belive that this logic rightly deserves to live in the entity bean, do you thereby write off any re-use of the bean? How do you intend to handle muliple paths of execution sharing the same entity with differing logic? If this is such an anti-pattern then share with us all your view of the pattern. The definition of anti-pattern isnt just a pattern youd ont like.
Internet Applications Divsiion
Always a pleasure to do polemics with you.
1) Session Beans are still a bunch of procedures. The difference between us is that your on app server side, so you can probably see some OO while I am on app developer side where there is none.
(a) Encapsulation. A method like Teller.transfer(fromAccount,toAccount, amount) (I try to be specific) is a clasical example of procedural code. Not to say that structured programming is bad while OO is good, far from me this thought. So encapsulation doesn't make OO because procedural code has that as well as OO.
Pascal and ADA are clear examples where Teller can be a unit (module) and it behaves exactly as your Teller session bean.
It's wright that in C it would be less ellegant:
teller_Transfer(teller, fromAccount,toAccount,amount) but it is encapsulation nevertheless.
I would say that non-encapsulation makes you say that it is not OO ( and not structured/procedural as well).
As a matter of fact, aside from Assembly, old Basic and old Fortran and of course, rookie programmers everybody else uses encapsulation. So I hope you'll agree to drop this point.
It's like saying (my product it's good because it meets all the minimum standards).
(b). Polymorphism. Let's say method overloading is not by far an OO only concept and not polymorphysm.
As to what regards true polymorphism you're right, a Session Bean interface has the basics of polymorphic behaviour, but I'm affraid it's only about the separationm between the interface and the implementation, which is something that every reasonable Pascal, C or Ada programmer will do seamlessly.
So we are talking merely of a client/server contract exposed through an interface.
Polymorphism shows it's true OO nature, only when you integrate the generic interface in generic algorithms where you have many different object interacting with each other through generic interfaces, a class of examples beiing algorithms on collections.
Client to Session Bean interaction IMHO it's not by its nature a demonstration of polymorphism, rather a client/server contract.
(c) Inheritance. If a component model doesn't support inheritance it's not OO, like Visual Basic. If the OO is only in the underlying implementation you may be very happy as an implementor developer, while I, as an app developer, I'm not quite.
My view of OO entities is object = data + behaviour + external contracts (where you put polymorphism and the like).
So, IMHO, Session Beans are not first class OO concepts.
Let me be clear, I don't say that Session Beans are necessarily bad because they are not OO. Most OO systems have to have procedural like stubs, point of entries, facades even a main method, and so on.
I say Session Bean as facade to Entity Beans is bad. While Entity Beans, if they were spec'ed correctly, would have bean the true OO entities .
But just to say that we put a Session Bean facade and we don't loose OO characteristics it doesn't sound true to me.
2) I think we completely agree (almost) on this point.
Many systems do have a structural data model and it's right to reflect that in the design.
However, I know of real life situations and real life software systems software systems that do have polymorphic aspects in data modelling, but those are excceptions.
Also you are right that "If anything, the sillyness of simply encapsulating flat data inside of mostly flat classes is more an anti-pattern that anything".
However, I would argue that "DAO" as they are in J2EE Blue Prints Java Pet Store sample are almost equally silly.
If you would use those type of objects instead of Entity EJB in Session Beans, at least you'll have less overhead and no unnecessary management from the part of App Server.
However those are also a bad example.
So, only if this would hold true, wouldn't it make the "pattern" an anti-pattern ?
3. InterBeans calls overhead.
(a) You launched a nice ricoche on your BEA coleagues.
If BEA passes my arghhuments belonging to my user defined classes as referrence then they should not get the J2EE certification.
Or at least they should clearly WARN the developer that they do.
It follows that the original objects passed as arguments can be modified by the code invoked which is not necessarily the worse of evils but one has to be aware of.
(b) If I choose to pass object arguments and not primitive types and certainly not remote references (such as call-backs), I would have to mark my objects Serializable. Maybe, I would better make them Externalizable, but I'm affraid these has been lately "forbidden".
However, I would still try to see if an app server honors the Externalizable inspite the spec.
This let's say very often the case, because we are talking OO here, aren't we ?
So, the overhead is there, it's in the spec we can't do nothing about it but find better models.
Sometimes I wonder why smart guys like you Dave, or many other people who try very hard to make a good implementaions of the J2EE bible, don't put real pressure on Sun to do their job well (not writing the spec, but THINKING A GOOD MODEL).
You'll soon have another "little monster" on your hands, namely JDO, other tons of marketing money and pressure from your marketing department and potential clients to make it work somehow.
I'm lucky to develop applications and not application servers, am I not ?
(c) You may think of it as very efficient from your point of view and I do believe you. You did the best you could while remaining faithful to the EJB spec.
However, my idea of efficiency would be no marshalling at all, when it's not needed.
(d) Since we have had other polemics, I would expect you to skip "easy" arguments like this.
Instance pooling and avoiding constructors, GC and such, common, you can do that yourself in one hour or less, you grab it from a dozen open source projects, but you don't make your objects Entity Beans because they offer you instancer pooling.
And certainly you don't throw money in an app server because it offers you instance pooling.
Let's drop this, should we ? Instance pooling where it applies is just a minimum reuqirements/ does not disqualify argument.
As to what is a good pattern?
It depends because we referred to two problems.
For the intiail target problem: "minimizing network overhead between the client and servers", certainly a facade will do the trick.
Just not a facade to Entity Beans that takes the logic out of where it belongs. (the entity specific logic should belong to entities, certainly not Enitity EJBs, but also not to the facade)
Also another way is replicating partial object graphs bewtween client and server because usually the client needs acces to those objects anyway in many situations. The client then calls methods on the object graphs locally , and at the end of the transaction the object graphs (or the differences where it makes sense) is sent back to the server that will propagate to the database.
So, you may like the pattern and declare it a pattern, not an anti-pattern. For me it's still an anti-pattern because it has certain bad consequences when applied, and to some of these consequences you agreed.
As to what regards the concrete problem you raised - how do you differentiate between withdrawing cash and making other type of payments from an account - I'm already too long with this message, so I'll ask you to credit me (us) that we can solve that within the account class and not in the facade.
Let's be more specific an accoutn has a 3% penalty for cash withdrawals, incentives for some type of payment, line of credit for other type of payments and so on. Of course you put this logic in the Account class and not in a facade.
I would have to say that I agree with Costin on the "session bean facade with business rules" pattern. To me this is a major step backwards. Getting "reusable" data containers provides very little value to me, the behavior is much more important.
There are many classic OO patterns and techniques that will allow you to customize behavior. An example that works well in the EJB world is to use a Strategy (or in IBM SanFrancisco terms a "Policy").
There are many many usefull pure OO patterns used in the SanFrancisco frameworks, and now in the Websphere Business Components frameworks, that cannot by applied if you limit yourself to the session bean facade pattern.
The problem that I see is that these patterns cannot be applied to entity beans, unless you allow your entity beans to be reentrant (see my thread "Reentrant Entity Beans and EJB server design issues").
Dont let my comments here be positioned to say that I am a fan of entity beans overall. But the original question was from someone who was using entities.
Internet Applications Division
I understand what you are saying when you say that placing the business rules in the session bean allows you to easily reuse the entity bean, and create another session bean allowing you to change the business rules.
My question then is, where does the common behavior go?
"Dont let my comments here be positioned to say that I am a fan of entity beans overall. But the original question was from someone who was using entities. "
So if your're not a fan of entity beans overall, how can you say that "Session Bean as Facade to Entity Beans" is a good pattern ?
What do those Entity Beans have that special in this case?
I caught you, didn't I ?
No Costin..... You've caught nothing. The customer asked if using facade with enties was a good pattern and hence I answered that. They did not ask what a good pattern for developing distributed applications was. I answered what was asked. Hence my later clarification.
I think you and I need to go out for a beer at JavaOne. Might be quite sporting :)
Internet Applications Division
Ok Dave, I'll bite. If in your humble opinion "They did not ask what a good pattern for developing distributed applications was", what other patterns should we be considering in our architectures?