EnterpriseJavaBeans refers to a specification for a server-side component model. The model was originally defined in late 1998, and was supported by WebLogic (since acquired by BEA) and IBM in its WebSphere product. Later supporting vendors included NetScape (later iPlanet, later still Sun), Oracle, and numerous others. (See EnterpriseJavaBeansServers for the current list). The spec itself is copyrighted by Sun, and is under control of the JCP (http://www.jcp.org). It has progressed through versions 1.0, 1.1, 2.0, 2.1 and now 3.0(May 2006).
While EJB originally stood on its own as a spec, since Dec 1999 it has been rolled into J2EE, the family of specs owned by Sun and JCP.
Originally, EJB promised compatibility with existing CORBA code and a simpler component object model, but the former has not really panned out as a key benefit, and the simplicity of EJB is still being debated. For more information on the spec see http://www.javasoft.com/products/ejb/index.html.
The really nice thing about EJB is that you don't have to write the server. That is, the specification dictates some properties that the bean components have, and the services a container must provide, so if you write a valid bean you can assume the existence of services such as connection pooling, transaction monitoring, security, etc. You can provide methods that activate or "passivate" the bean so that the server can control it, and then you just plug it in and let concurrency be SomebodyElsesProblem (but see ThreadsConsideredHarmful). The same is true for persistence; you can tell the container which fields are to be persistent on an appropriate bean (EntityBean) and let it worry about the SQL.
Does nobody think EJBs are a little bit 'Hacky'. That is that they're not, quite, em, there. Or Coherent or something... Do you have a specific area you wish to discuss?
I heard a talk by AlanKnight in which he said that EJB doesn't work. More precisely, session beans are fine, but entity beans are impossible to make efficient. There are two kinds of entity beans, container managed persistence and bean managed persistence. Bean managed persistence requires fetching one at a time; a query can return a set of IDs of beans, but then you have to make a separate SQL query for each one. Container managed persistence is more efficient, but limited in what you can represent. There is a one to one mapping between bean types and tables, and you can't model relationships between beans. The result is that anybody who wants to implement a high-volume server will ignore entity beans and use a third-party object-relational mapping tool like TopLink. (Alan is one of the developers of TopLink, though he no longer works for the company that wrote it.)
So, is this true? I have never programmed EJB, so I don't know.
That's definitely a point-in-time statement. Yes, the current tools are limited, mostly because of limitations in the existing (EJB 1.0 and EJB 1.1) specifications. However, when EJB 2.0 is released in its final form, expect to see those limitations removed and tools like TopLink and CocoBase generate all CMP EJB's for various servers... -- KyleBrown
Except that (with the current final draft 2), every persistent object will need at least 2 interfaces now, almost guaranteeing the need for code generation to keep productivity at a reasonable rate... -- StuCharlton
On my previous project I made my own code generator that pulled in reports from ERWin. Very cute - the ERWin comments painstakingly maintained by the DBA wound up in the javadoc. Just like a bought one -- PaulMurray
The above could use a little clarification. There are two kinds of enterprise beans: session and entity. Session beans are stateful or stateless, but I don't think it was the speaker's intent to discuss those. Of entity beans, there are two models for persistence: bean managed and container managed. Persistence basically means storing and loading from permanent media. Bean-managed persistence implies that your bean implementation will have to store and load each bean each time it changes, since your bean is not aware of higher level transaction groupings. EJB 1.1 specifies container-managed persistence, but how many containers have implemented it, and how smart?
I can't think of any EJB 1.1 server that doesn't support simplistic CMP (where the fields map to rows in a database table). Support for entities (both BMP and CMP) was made mandatory in EJB 1.1, and the only 1.0 server I can think of which didn't support it is Oracle's. That said, the support for CMP varies. WebLogic's is pretty simplistic, but you can plug in TopLink for a lot more power. WebSphere's is also pretty basic, but you can design complex relations and associations in VisualAgeJava (and one day they'll fix it so you can define them outside of VaJ, as well). GemStone's app server, for instance, sits directly on top of the object database. With EJB 2.0, however, it will be required that containers provide support for relationships between objects. Until last week (it's now 1st May, 2001), this was going to be via dependent objects. The ProposedFinalDraft? 2 has changed the rules slightly, and I'm still trying to get to grips with it. However, associations are definitely still permitted. In addition, beans will be able to be partly loaded (depending on the finder method use to locate them), and returning a collection is going to be more efficient because of that. EjbTwo makes a big difference to the power, usability, and scalability of entity beans. -- RobertWatkins
I'm suspicious of EJB's. They look good for simple object persistence, but fall over when instances are not independent e.g. when doing a complex query against many tuples in a table. This requires SQL to do efficiently, since efficiency relies on data reduction at the database, not at the object level. I can imagine various scene-graph solutions, but in the end SQL is king of the batch query. Anyone care to explain why I'm wrong? -- RichardHenderson
I'll give it a go. :) Firstly, the container knows and understands the data of the entity beans. It knows the types of queries that are performed against said data. It knows the structure of the data (a good container would even be able to optimize the structure for you). The container should be capable of designing highly optimized SQL queries for you. SQL, after all, can be analysed and an optimal query determined through repeatable logic. Why would you want to hand-write it when you can get the container to do it for you? To me, this argument is a lot like the early days of optimizing compilers; purists thought optimizations should be done by hand, whilst others wanted the compilers to get better at it. -- RobertWatkins
Does such a container exist? I can imagine hacks to do stuff like a complex aggregation via a temporary table but is it still EJB in those situations? My experience has not been good on this. In the end we used session beans getting wrapped result sets from stored procedures. Worked great. Extremely fast. Our friends using CMP had a nightmare with concurrency issues and scalability. Then they turned on caching and got hyper-speed garbage. All classic symptoms of a flawed distributed architecture. I'm sticking with keeping SQL at the database with a functional interface. Much better leverage of resources.
TopLink generates pretty good SQL and can also map to custom SQL. Its CMP implementation works with WebLogic and WebSphere... and if you want to use it's proprietary API I think it also supports others like Borland. WebObjects 5 may also be of interest in this area when it comes out.
I heard TopLink was good. Unfortunately this doesn't fix the fact that EJB's add an explicit indirection to the database and don't handle rowset logic. Are we supposed to load each row individually? If I only want one column from a table, do I have to load the whole row, then throw it away afterwards? It strikes me that as soon as we wish to look at data as a set of data, EJB's are a poor architectural model to work with. Good for toy object persistence, but no good as an O-R mapping. I hope Toplink haven't completely deprecated their standard Java product for an EJB only product. Big mistake IMO. -- RichardHenderson.
Arrggh.. Here it is again. EJB's do NOT require an explicit indirection into the database. You do NOT have to load each row individually as a separate SQL call. As I discussed on another page, CMP EJB's are free to load an entire ResultSet in a finder method (and in fact do in many implementations) and are also free even to implement logic that does lazy fetch of column values if they want. Don't confuse the "standard" implementation of BMP that the books show you with what CMP must do. And finally, if you're looking at a set of Data as a relational model, you're not doing O-R mapping. Entity EJB's are the end product of O-R mapping. If that's not what you want don't use them. -- KyleBrown
Here I have a question: how come the StandardWay of doing things is the WrongWay?? In my experience with BMP I was obliged to do many things, as control when the fields are dirty. It is interesting to see that accordingly to the J2EE specification, PASSIVATE and ACTIVATE must use the database. So, we had to optimize by hand, not saving what was not changed. -- GeraldoXexeo
Entity EJBs are not THE end product of O-R mapping. They are not even among the good products of O-R mapping ideas. EJB specifications is already full of anti-patterns. So Richard is absolutely right. Some of the anti-patterns in the EJB spec will be uncovered as they will try to erase their traces in the upcoming versions of the spec, while struggling to maintain backward compatibility.
Kyle, if relational techniques were irrelevant then why did Sun do EJB 2.0? It has a clunky version of SQL (called OQL), still downplays the fact that EJB's are really client-side cursors with poor facilities. Performance is still going to suck. Indirection is inevitable since a tuple must be loaded to be examined. Associations are still poor and weakly defined. EJB's look like a Microsoft style territory grab by Sun. It will sell big boxes like Windows sells fast PCs (which is why Sun and IBM are in bed). It will always be embarrassed by systems that don't attempt to separate database logic from databases. This is a fundamental performance issue, and databases are performance hogs.
How does EJB relate to JDO? That seemed to make sense. As it is, Microsoft will be happy. C# is all about performance; but then they aren't trying to sell hardware.
An interesting 'Best Practice' that has emerged over the past three or so years of EJB development is the idea that Entity Beans should never be accessed from the client, but only through a Session Bean facade layer. This practice is obvious for performance reasons (fine grained access to distributed objects is slow), and is espoused by some of the EJB architects (IBM), but it calls into question the motivation for the existence of entity beans. If we're not accessing the beans remotely, then we must be using them for something else, like CMP, or declarative transaction demarcation, or something. Until 2.0, containers' CMP implementations couldn't possibly handle complex object graphs efficiently (and most didn't even try), and declarative transaction demarcation on session bean methods is generally sufficient. So, until 2.0 at least, entity beans were far more headache than they were worth. I'm still not sold that using simple objects for your domain model, and a tool like TopLink for the O-R mapping, isn't still the best way to go.
On the plus side, using simple objects and TopLink or something like it does work very well. I've had no problems with the approach at all, so Entity Beans have simply been an easily ignored wart on an otherwise useful platform. -- RobertGreayer
I have been thinking about EJB's for a while now. They make some simple (architectural) errors if one uses them in all flavours. Firstly, the stateful session-bean. If we proxy client state in the middle-tier, then we create a problem of distributed data. Similarly, if we proxy database state in the middle tier, then we create a problem of distributed data.
For stateful session-beans some problems are ones of performance, error detection, load-balancing and error recovery (See DoesAnyoneActuallyUseStatefulSessionBean). For entity-beans some problems are ones of performance, data synchronization, load-balancing and error-recovery.
All these issues result from the mistake of doing things in the wrong places. They are then partially solved by building very heavyweight physical and logical infrastructure, which sells huge application servers and huge boxes to run them on, i.e. back to the mainframe model of computation. I think this is regressive.
The solution is not to use the faulty components, which means the middle tier need only use transaction oriented (stateless) session-beans in a service arrangement. Of course then we don't actually need all the big infrastructure. We can run it all on a bunch of pc's if we want to, in as many languages as we want to, using legacy kit, as and when we choose. Data is kept in a canonical form, in one place, accessible by all. Querying/synchronization of data is done in one place. Logical and physical encapsulation is maintained.
A great deal of the churn, duplication, pain and fragility of EJB's would go away if we used the simplest of architectural principles: everything in its place and a place for everything. It isn't OO (metadata anyone?), it isn't transparent, it isn't efficient, it isn't robust, it isn't agile, it isn't big and it isn't clever....:). ---RichardHenderson.
EJB isn't OO (metadata anyone?), it isn't transparent, it isn't efficient, it isn't robust, it isn't agile, it isn't big and it isn't clever....
I agree entirely. Did you take a look at ThePrevayler?
I keep hearing, "Sure, EJB has a lot of downsides, but look at all the stuff it gives you. This is all stuff that an EnterpriseApplication needs, and you don't want to be ReinventingTheWheel for all of this stuff, you want to focus your development efforts on your core competencies." This seems to be in contrast to DoSimpleThings and YouArentGonnaNeedIt.
YAGNI means that you probably shouldn't write things as EJB's at the beginning of the project. But when your requirements evolve to require concurrent, transactional, possibly stateful, persistent, shared & private objects in a distributed system that also need to be packaged for future organizational reuse -- EJB solves those things. And you'd be surprised how many systems "need" those features in large enterprises (geographically distributed servers, remote development teams, 2-phase commits, high number of client requests, etc). DoSimpleThings really means DoTheSimplestThingThatCouldPossiblyWork, where possibly is the key word next to simplest. All software projects need to be viewed within an organizational context that may not allow the simplest pure technical solution. --StuCharlton
EJB wasn't designed to solve your problems. Perhaps it wasn't even designed to solve anybody's problems, but maybe everybody's problems.
So, what's good about EJB?
(1) Optional Distribution with Stateless Session EJB's
(2) Optional 2-PC connections with JCA (to things like CICS and JD Edwards), JDBC and JMS.
(3) A tolerable role-based security model for the stateless session beans.
Personally, if that's what you use (and in 9 cases out of 10, that is all I use with our customers) then it's a pretty useful framework. Again, if that's all you use, then there's very little overhead to learn (the learning curve for this part is comparable to using regular RMI) and the runtime overhead is comparable to other distribution technologies for Java as well. --KyleBrown
I am amazed to be reading this. Are those really the Top 3 Good Things about Ejb? Is it really true that 9 out of 10 times this is all you use? The thing is, I respect the experience, viewpoints, and opinions of KyleBrown, so this is a pretty strong indictment of everything else in the spec. Wow. --DinoChiesa
OK, so maybe 9 out of 10 was too strong. Perhaps 6 or 7 out of 10 is closer. To really get to 9 out of 10 I'd have to also add CMP Entity Beans, which (in moderate doses) can be a fairly useful database access mechanism for simple cases and Message-Driven Beans, which are a TRULY useful idea --KyleBrown