Yesterday, Linda DeMichiel announced the changes coming in EJB 3.0. There was a lot to digest in her presentation, and I think it will take a while for people to figure out the full implications of the new spec. So far, most attention has focused upon the redesign of entity beans, but that is most certainly not all that is new! The expert group has embraced annotations aggressively, finally eliminating deployment descriptor XML hell. Taking a leaf from Avalon, Pico, Spring, Hivemind, etc, EJB will use dependency injection as an alternative to JNDI lookups. Session beans will be POJOs, with a business interface, home objects have been eliminated. Along with various other changes, this means that EJB 3.0 will be a much more appropriate solution for web-based applications with servlets and business logic colocated in the same process (which is by far the most sane deployment topology for most - but not all - applications), without losing the ability to handle more complex distributed physical architectures.
What is amazing is the broad consensus in the EJB Expert Group - all the way from traditional J2EE vendors like BEA, to we open source kiddies - about what was most needed in EJB3. There has been a lot of listening to users going on, which took me by surprise. Linda's leadership is also to be credited.
But anyway, this is the Hibernate blog, so I'm going to discuss persistence....
EJB 3.0 adopted a POJO-based entity bean programming model, very much similar to what we use in Hibernate. Entity beans may be serializable. They will not need to extend or implement any interfaces from javax.ejb. They will be concrete classes, with JavaBeans-style property accessors. Associations will be of type Set or Collection and always bidirectional, but un-managed
. (Referential integrity of bidirectional associations is trivial to implement in your object model, and then applies even when the persistent objects are detached.) This model facilitates test-driven development, allows re-use of the domain model outside the context of the EJB container (especially, DTOs will be a thing of the past for many applications) and emphasizes the business problem, not the container.
Hibernate Query Language was originally based upon EJBQL, ANSI SQL and ODMG OQL, and now the circle is complete, with features of HQL (originally stolen from SQL and OQL) making their way back into EJBQL. These features include explicit joins (including outer joins), projection, aggregation, subselects. No more Fast Lane Reader type antipatterns!
In addition, EJBQL will grow support for bulk update and bulk delete (a feature that we do not currently have). Many users have requested this.
For the occasional cases where the newly enhanced EJBQL is not enough, you will be able to write queries in native SQL, and have the container return managed entities.
EJB 3.0 will replace entity bean homes with a singleton EntityManager object. Entities may be instantiated using new, and then made persistent by calling create(). They may be made transient by calling remove(). The EntityManager is a factory for Query objects, which may execute named queries defined in metadata, or dynamic queries defined via embedded strings or string manipulation. The EntityManager is very similar to a Hibernate Session, JDO PersistenceManager, TopLink UnitOfWork or ODMG Database - so this is a very well-established pattern! Association-level cascade styles will provide for cascade save and delete.
There will be a full ORM metadata specification, defined in terms of annotations. Inheritance will finally be supported, and perhaps some nice
things like derived properties.
Because everyone will ask....
What was wrong with JDO? Well, the EJB expert group - before I joined - came to the conclusion that JDO was just not a very appropriate model for ORM, which echoes the conclusion reached by the Hibernate team, and many other people. There are some problems right at the heart of the JDO spec that are simply not easy to fix.
I'm sure I will cop enormous amounts of flak for coming out and talking about these problems in public, but I feel we need to justify this decision to the community, since it affects the community, and since the EG should be answerable to the community. We also need to put to rest the impression that this was just a case of Not Invented Here
.
First, JDOQL is an abomination. (There I said it.) There are four standard ways of expressing object-oriented queries: query language, query by criteria, query by example and native SQL. JDOQL is none of these. I have no idea how the JDO EG arrived at the design they chose, but it sort of looks as if they couldn't decide between query language and query by criteria, so went down some strange middle road that exhibits the advantages of neither approach. My suggestion to adopt something like HQL was a nonstarter. The addition of support for projection and aggregation in JDO2 makes JDOQL even uglier and more complex than before. This is /not/ the solution we need!
Second, field interception - which is a great way to implement stuff like Bill Burke's ACID POJOs or the fine-grained cache replication in JBossCache - turns out, perhaps surprisingly, to be a completely inappropriate way to implement POJO persistence. The biggest problem rears its head when we combine lazy association fetching with detached objects. In a proxy-based solution, we throw an exception from unfetched associations if they are accessed outside the context of the container. JDO represents an unfetched association using null. This, at best, means you get a meaningless NPE instead of a LazyInitializationException. At worst, your code might misinterpret the semantics of the null and assume that there is no associated object. This is simply unnacceptable, and there does not appear to be any way to fix JDO to remedy this problem, without basically rearchitecting JDO. (Unlike Hibernate and TopLink, JDO was not designed to support detachment and reattachment.)
Proxy-base solutions have some other wonderful advantages, such as the ability to create an association to an object without actually fetching it from the database, and the ability to discover the primary key of an associated object without fetching it. These are both very useful features.
Finally, the JDO spec is just absurdly over-complex, defining three - now four - types of identity, where one would do, umpteen lifecycle states and transitions, when there should be just three states (persistent, transient, detached) and is bloated with useless features such as transient transactional
instances. Again, this stuff is just not easy to change - the whole spec would need to be rewritten.
So, rather than rewriting JDO, EJB 3.0 entities will be based closely upon the (much more widely adopted) dedicated ORM solutions such as Hibernate and TopLink.
Myself, I'm working on something *really* cool (in Java) that I hope is even better than PHP.
But as for the vast bulk of the Java community - you're NOT seeing the light.
Not sure how you arrive at the "99%" conclusion. We've been happily using EJB+Hibernate+Spring running in an App Server container, such that all the resource/transaction management can be externalized and be done declaratively, and that the whole thing is deployed in a J2EE EAR.
The Hibernate/Spring part doesn't know that it's run in a J2EE/EJB environment. Conversely, the J2EE EAR doesn't need to care if it is implemented using Hibernate/Spring. Just a standard J2EE app that can be run in any J2EE app container.
This combination allows a clean separation of Web/Presentation tier and the Business tier/Data Access layer.
It's certainly simpler to just have Hibernate+Spring. But one can get the best of both worlds (Power/Flexibility + Standard component/Simplicity) with EJB+Hibernate+Spring.
---
You can do the same without the container. The problem with the container is that it really gives you nothing you can't in standalone fashion with several third party components. It just adds to the cost equation.
>The Hibernate/Spring part doesn't know that it's run in a J2EE/EJB environment. Conversely, the J2EE EAR doesn't need to care if it is implemented using Hibernate/Spring. Just a standard J2EE app that can be run in any J2EE app container.
---
You certainly have not have to deal with an application that needs to run in any container.
This combination allows a clean separation of Web/Presentation tier and the Business tier/Data Access layer.
---
Clearly, you're just doing web/presentation petstore type stuff.
It's certainly simpler to just have Hibernate+Spring. But one can get the best of both worlds (Power/Flexibility + Standard component/Simplicity) with EJB+Hibernate+Spring.
---
I agree with you on that one. But you don't really need the container. The container is just a method for IBM and BEA to make money. I'd rather pay $5k to Gavin then to give it to BEA.
Just some thoughts.
[quote]Taking a leaf from Avalon, Pico, Spring, Hivemind, etc, EJB will use dependency injection as an alternative to JNDI lookups.[/quote]
Taking a leaf? It's rather a shameless imitation of Spring's recommended development model: It's all about POJOs and setter injection. And there hasn't been a single credit to Spring and co in Linda's talk... (but lots and lots of credits to Hibernate).
Of course, EJB 3 is still about components getting deployed to a full EJB container, with separate classloader, deployment units, etc. There's a strong difference in terms of flexibility of deployment: EJB 3 can by design never match Spring's capability of adapting to all sorts of environments, even if adopting the same development model.
[quote]So, rather than rewriting JDO, EJB 3.0 entities will be based closely upon the (much more widely adopted) dedicated ORM solutions such as Hibernate and TopLink. [/quote]
Why oh why does this have to be part of the EJB spec? Why not doing a separate O/R mapping spec - no matter if within or outsider the JDO scope? There's no technical reason for tying this to an EJB container: This seems to be all about politics... completely neglecting the need for O/R mapping outside a J2EE server.
It is not good enough to have some EJB 3 EntityManager implementations that can run outside an EJB container. It's still part of the EJB spec, not allowing certification for anything but a complete EJB container implementation (which includes the entire EJB 2 model).
Juergen
Well if you believe what Gavin said in his EJB->Hibernate->EJB 3.0 talk, that is not true. Hibernate will still be around in order to provide a "playground" of cool new features/ideas. I mean isnt that what Hibernate is/was? A very cool new idea that is beyond the specs?
Rather EJB 3.0 is killing itself (if it hadn't already) because it is playing the role of catchup and not leader.
On the plus side, the people that only want to implement things via 'standard' J2EE will be able to use the features of Hibernate without having to explicitly use Hibernate.
They'll just lose out on any cool features of Hibernate that will come in the future after EJB 3.0 is released.
Why does such a O/R mapping spec with a SQL-style query language have to be part of the EJB spec? As I elaborated above, this could easily be a standalone spec that's usable in any environment.
The EJB spec could simply refer to that separate spec for persistence. With it being part of EJB, no persistence tool vendor can implement the O/R mapping spec - just J2EE server vendors can.
Juergen
Jeff
Knock yourself out!
[quote]
It is ridiculous to claim that someone invented pojo development and setter injection.
[/quote]
I never claimed that Spring "invented" the setter injection concept. Nevertheless, Spring certainly pioneered a sophisticated implementation of it - and brought that development model into the mainstream.
The very article by Martin Fowler that finally defined the term "setter injection" clearly referred to Spring as sort of reference implementation. EJB 3 is undoubtedly influenced by that particular solution.
[quote]
Gimme a break. These little IoC patterns Spring uses have been around for quite a while now. Get off your high horse, why should you get credit, you just ripped them off from someone else anyway.
[/quote]
Give me a single public example of setter injection before Spring (or its predecessor, the interface21 framework) arrived. Avalon just uses service location. Pico's and HiveMind's support for setter injection came significantly later.
My main point is: It would be fair to give credit to lightweight container products just like to Hibernate. After all, Hibernate hasn't invented O/R mapping or O/R query languages either - so why explicitly mention it 10 times then?
Juergen
Actually, it is very easy to fix and exactly because JDO intercepts fields access.
Of course that would be in contradiction with the spec, but this is a very minor change anyway.
>Proxy-base solutions have some other wonderful advantages, such as the ability to create an association to an object without actually fetching it from the database, and the ability to discover the primary key of an associated object without fetching it. These are both very useful features.
JDO has hollow state for such things. This is an implementation decision at what moments it fetches object from the database.
>So, rather than rewriting JDO, EJB 3.0 entities will be based closely upon the (much more widely adopted) dedicated ORM solutions such as Hibernate and TopLink.
Who said that it is impossible to build JDO impl on top of Hibernate?
> small dicked children...
lotsa rhetoric few results
>Comparing the defiition of metadata in XML vs. >in the source code as annoatations, I see the >advantage of using an XML schema or DTD for >validation purposes. Is there such equivalent or >similar "Annotation schema" being available (or >to be developed) to allow validation of the >metadata specified via annotation (in product >such as XDoclet) ?
Annotation are by design validated. They are basically interfaces, which are validated *at compile time*. Do you expect more ?
As usual there are validation you can't do on annotation itself, but it's the same for DTD.
1- Who the hell is Spring?
2- It is ridiculous to claim that someone invented pojo development and setter injection.
>specification, defined in terms of
>annotations
Comparing the defiition of metadata in XML vs. in the source code as annoatations, I see the advantage of using an XML schema or DTD for validation purposes. Is there such equivalent or similar "Annotation schema" being available (or to be developed) to allow validation of the metadata specified via annotation (in product such as XDoclet) ?
Hanson
Taking a leaf? It's rather a shameless imitation of Spring's recommended development model: It's all about POJOs and setter injection. And there hasn't been a single credit to Spring and co in Linda's talk... (but lots and lots of credits to Hibernate).
Of course, EJB 3 is still about components getting deployed to a full EJB container, with separate classloader, deployment units, etc. There's a strong difference in terms of flexibility of deployment: EJB 3 can by design never match Spring's capability of adapting to all sorts of environments, even if adopting the same development model.
So, rather than rewriting JDO, EJB 3.0 entities will be based closely upon the (much more widely adopted) dedicated ORM solutions such as Hibernate and TopLink.
Why oh why does this have to be part of the EJB spec? Why not doing a separate O/R mapping spec - no matter if within or outsider the JDO scope? There's no technical reason for tying this to an EJB container: This seems to be all about politics... completely neglecting the need for O/R mapping outside a J2EE server.
It is not good enough to have some EJB 3 EntityManager implementations that can run outside an EJB container. It's still part of the EJB spec, not allowing certification for anything but a complete EJB container implementation (which includes the entire EJB 2 model).
Juergen
Sure, *you* did - thanks for that, BTW :-) I was rather referring to Linda's talk... (Your blog entry just gave the first occasion to voice my point of view, one day after the talk.)
> I explained this in my talk. Declarative session management; "persistence context" management as an aspect.
I remember, but that's all add-on services. As Spring shows (which wasn't mentioned either), those can easily be added on top of an existing persistence tool like Hibernate. No need to make the entire persistence solution an inherent part of the container.
> And to provide a nice migration path away from CMP 2.1, toward POJO entities.
That's the political motivation, i.e. there needs to be something credible that's still called "EJB Entity Beans", even if it's a completely different solution. However, technically speaking, the same could be achieved by referring to a separate O/R mapping spec, offering first-class support for it within an EJB container (similar to what Spring does for Hibernate).
As I outlined, the main advantage of a separate persistence spec would be reusability in any environment: That would finally result in a general Hibernate-style O/R mapping specification for Java. And it would allow Spring to support it in the same fashion as an EJB 3 container (i.e. analogous to Spring's current support for native Hibernate).
Juergen
You are sending confusing messages. HB users are grateful for what you've done but you need to be open and honest about your plans since they affect many. Thanks
> It would be fair to give credit to lightweight container products
I thought I just /did/!?? I referenced spring by name....
> Why does such a O/R mapping spec with a SQL-style query language have to be part of the EJB spec?
I explained this in my talk. Declarative session management; "persistence context" management as an aspect.
And to provide a nice migration path away from CMP 2.1, toward POJO entities.
Gavin, if you needed the money, why didn't you start a church, religion or even a multi-level marketing system like AmWay. It is very disrespectful to kill your own children. So please quit bastardizing your own work. If you needed the money, you could've called.