To build a CMP 2.0 entity you had to know many details. So you class had to implement the Entity Bean interface. Then you were forced to implement the lifecycle (setEntityContext, ejbLoad,ejbStore,ejbRemove, ejbActivate,ejbPassivate) and also the ejbCreate and ejbPostCreate methods. After this local (hopefully not remote) interfaces had to be implement. The development of a CMP 2.0 was tedious "monkey" work, so it could be easily generated (e.g. with XDoclet). Until now it was only tedious - but not complex.
Every participant of an J2EE course was able to deploy a CMP in the past years :-). The cool story here: if you compare CMP 2.1-spec to hibernate, Kodo,Toplink or JDO docs, you will find out, that CMP 2.0 was the easiest one. Reason: CMP 2.1 had not addressed many necessary issues like (relationship) caching, eager/lazy loading, locking or invalidation. In the practice, every vendor implemented own extensions, so that the CMP 2.1 with such extensions was usable, but also became much more complex. Regardless which product did you used, some facts remained stable:
- CMP 2.1 were NOT serializable.
- CMP 2.1 were only "stupid" OR-mappers
- CMP 2.1 often limited regarding SQL capabilities etc.
So long CMP 2.1. In the new, beautiful, transparent world, almost everything, what was proprietary, become now standardized (what is actually great). So the JPA-spec is more complex now - but also more portable and powerful. Conclusion: it is really easy to build trivial applications with POJOs, but in real world, you will still have to know many configuration options (just look at hibernate.properties or hibernate.xml, the hibernate spec, JDO, TopLink, Kodo, or JPA doc). In the "new" world the entities are serializable, no more stupid, and you can use powerful SQL queries - so now everything is possible. The transparent persistency is especially challenging in distributed world, where the persitent objects live on the server and the presentation layer on a client machine. So in every project you have answer at least the following questions:
- How many levels of your object hierarchy has to be transferred to the client? (in case your are loading your dependent objects eagerly - probably the whole database, in case you are working with lazy references - you will get a kind of "Unresolved Reference Exception")
- What happens when the client deletes a dependent object? Should it be also deleted on the server? (Just imagine: you have: a customer has three addressed, you transfer only two to the client. The client deletes one and send it back to the server. Should the client state be persisted?...and all two addresses deleted)
- Is the structure of the persistent entites is also suitable for the client (remember: im most cases you are not in "green field" projects, so you have also deal with legacy databases)
There are also many small "suprises" which remembers you that: ....Nothing is transparent :-). Just an additional example: a developer cloned a persistent object and merged it with the (in this case hibernate) session again. He expected to see the clone in the db - what not happens (you have to set the PK to null first :-)). Such problems were in the complex CMP 2.1-world simply not possible, because CMP were not so powerful. Developers were also forced to work with VOs, so also "Unresolved Problem Exception" cannot happen.
The content of this entry has actually nothing to do with Java or Java EE. Such challenges has to be to solve in every framework, environment and programming language. Just read my rails and transactions entry and especially the reactions from the ruby space (very interesting) :-) - there are no miracles....
It is very easy to criticize Java EE, but I do not see a real alternative to it. Distribution, transactions and persistence are hard problems, but they are not platform (especially Java and Java EE) specific... Java EE 5 - especially JPA are really great :-)