New Article on "Inheritance and EJBs" Posted on TheServerSide

Discussions

News: New Article on "Inheritance and EJBs" Posted on TheServerSide

  1. A new article, by Daniel O'Connor, "Inheritance and EJBs", shows how entity EJBs can be used effectively to represent business objects with inheritance and polymorphic behavior. It shows you how to implement entity bean inheritance with three sample CMP EJBs, demonstrating a polymorphic finder query and a couple of polymorphic method calls.

    Read "Inheritance and EJBs"

    Threaded Messages (31)

  2. Good stuff Dan. Seems like a good starting point for formally supporting component inheritance in a future rev of the EJB spec. Do you think this could go into a 2.x release of the spec, or would it have to wait for 3.0? Have you discussed this approach with any members of the EJB expert groups? It would be cool to see automated support for this kind of thing in XDoclet too.
  3. <tim>
    It would be cool to see automated support for this kind of thing in XDoclet too.
    </tim>

    Yes, it's possible. All those if/else statements and even the ejbCreate/postCreate can be autogenerated into the derived implementation class.

    Anyway, note that XDoclet doesn't support 'data model inheritance', what Dan is talking about, but the rest of component inheritance is supported. So if you have Party and Corporation, XDoclet automatically generates remote/home/pk/etc for Corporation that correctly derives from PartyIntf/PartyHome/etc. Overall even with this kind of automation it's still an ugly workaround imho for one of EJBs biggest limitations. The biggest problem is that base entity has to know about derived entities, provide ejbCreate/etc for each of them and so on. Probably even this hard dependency can be cleanly handled in the derived implementation class XDoclet's <entitycmp/> subtask generates but you see it's not a neat solution really.

    Ara.
  4. Very good article, Dan. My only complaint is that a few class diagrams would have made it a bit easier to understand. (But hey, we can read code, can't we ;-)

    What struck me with the solution is the high level of "hacking" an its unintuitiveness. So I thought this must be a job for a code generator.

    I'm one of Ara's colleagues in the XDoclet team, but also the author of Middlegen. Middlegen acts as an additional code generation layer between the database and XDoclet, generating XDoclet's input from the database's metadata.

    What do you think about generating EJBs that use this "fake inheritance pattern" with Middlegen in stead of XDoclet. The inheritance "hack" is done partly in the bean implementation classes. These classes is what XDoclet _reads_, and not what it _generates_. On the contrary, Middlegen _generates_ the bean class.

    DB --Middlegen--> Bean --XDoclet--> Homes,Interfaces,etc.

    Of course, in order to be able to do this, we need to provide Middlegen with some extra infromation about the inheritance, but that can be done via its Ant or GUI interface.

    What do you think?

    <aslak/>
  5. I think that EJBs (with all their moving parts) are designed for code generation, and that XDoclet is one of the best approaches out there. (MVCSoft's system tests are now being written with XDoclet.) The idea of using XDoclet for the code that implements polymorphism is quite good, and I think taking it the next step and generating the bean classes is even better. It's quite a small step to taking an existing database schema or UML model, hitting "generate," and having XDoclet bean classes all set up with the inheritance, delegation, polymorphism, etc. all in place!
  6. Why can't XDoclet or some other generator merge deployment descriptors of the base class with the subclass' DDs? It seems to me that the "deployment descriptor" inheritance (OK, call it component inheritance) is what's lacking here, otherwise Java inheritance mechanism works just fine. Weblogic 7, as an example, provides the ability to map a bean to multiple tables (yes, it is proprietary), so why can't we simply combine fields, finders and cmrs together in one DD?
    IMHO, creating dependency from base class to subclass defeats the purpose of the inheritance and kills the idea of entity beans being reusable business objects.

    Alexander
  7. <Alexander Ananiev>
    Why can't XDoclet or some other generator merge deployment descriptors of the base class with the subclass' DDs? It seems to me that the "deployment descriptor" inheritance (OK, call it component inheritance) is what's lacking here, otherwise Java inheritance mechanism works just fine. Weblogic 7, as an example, provides the ability to map a bean to multiple tables (yes, it is proprietary), so why can't we simply combine fields, finders and cmrs together in one DD?
    </Alexander Ananiev>

    XDoclet already does that. If you define a container managed field in a base CMP (or even BMP class because with XDoclet you can subclass a CMP from a BMP class and vice versa easily), and subclass from that base CMP bean, the derived one inherits all declared cmp fields and those cmp fields also appear in the generated deployemtn descriptor for the derived one. So as you say Xdoclet can "merge deployment descriptors of the base class with the subclass' DDs".

    <Alexander Ananiev>
    IMHO, creating dependency from base class to subclass defeats the purpose of the inheritance and kills the idea of entity beans being reusable business objects.
    </Alexander Ananiev>

    My impression is that you haven't understaood the 'data model inheritance' concept Dan is talking about. The trick is how you can handle inheritance in finder/cmrs/etc.

    Ara.

  8. >>The trick is how you can handle inheritance in
    >>finder/cmrs/etc

    Aha, thanks Ara.

    I thought I was missing something. Its the CMR's I hadnt considered (I've only previously done this with CMP1.1).

    For me its not a big difference whether you have to hand-dispatch the finders or the methods (effectively, the choice between the two approaches) - but the CMR's are a different thing. If you want your "polymorphic" Entity as a child in a CMR then, yes, you would have to implement it exactly as Daniel has done.

    However, I am fairly confident that the leading CMP containers will implement this fairly soon - but in order for it to be useful, it is a matter of addition to the CMP spec.

    -Nick.

  9. <quote>
    Do you think this could go into a 2.x release of the spec, or would it have to wait for 3.0
    </quote>

    2.1 is still in public review, so I suggest that if you want this, start making some noise. It should be early enough to get something done.
  10. "Seems like a good starting point for formally supporting component inheritance in a future rev of the EJB spec. Do you think this could go into a 2.x"

    Well, the approach I described works within the existing EJB specification. The basic idea to describe relationships and finders in terms of the base component might be part of a component-inheritance solution, but there are many tricky issues to address either way. The spec version that addressed these issues would definitely be a major revision!

    It would be nice to have spec support for delegating method calls, to avoid embedding this delegation code in the base class--which as Ara and Aslak rightly point out is not ideal.

  11. Very interesting, but with JDO is so clean...

  12. this is a good article, as was to be expected from the author, whom I regard as an outstanding and (almost) independent expert in the field. However, I do have one complaint, which might in fact be called a major one:

    Daniel purports to refute the criticism that entity EJBs don't support inheritance. He does this by providing an example how an inheritance-based data model can be implemented in EJB by introducing hand-coded (or possibly generated) resolution mechanisms.

    Now, to me there is a huge difference between "supporting" inheritance, and "being capable of representing" it. It is definitely possible to represent inheritance with plain SQL/JDBC, and the same goes for EJB. But that is a long way from truly supporting it.

    What Daniel shows us is that there IS a way, however cumbersome it may be, to circumvent the shortcomings - provided you have an EJB container that at least supports the basic requirements made by the presentation, i.e., identifying foreign keys (aka migrated foreign keys as primary keys).

    Note that this latter simple requirement already poses major problems the EJB spec. To be fair, at some point the text correctly concludes that "In fact, there is no framework support in the EJB spec for inheritance and polymorphism".
  13. Thanks for taking the time to write the article, but to me personally this is anathema:

    public String getDisplayName()
    {
      String code = getTypeCode();
      if (code.equals("I"))
        return getPerson().getDisplayName();
      else if (code.equals("C"))
        return getCorporation().getDisplayName();
      throw new EJBException( "Unknown type" );
    }

    I understand that it's simple to do the dispatching this way (in the "superclass"), but I just don't think that the superclass should know about the subclasses like that.

    I haven't thought about this, but perhaps an application of the Command pattern might serve us well here.

    Either way this stuff really belongs in the spec.

  14. I understand your point of view. However, to get polymorphic behavior you need a dispatch mechanism. If the EJB spec doesn't address it, then the runtime can't (portably) provide it and the bean developer must instead.

    This article showed the simplest technique to provide this dispatch mechanism, to illustrate the idea. Many variations on this theme are possible. The one that Tim suggested and Ara and Aslak discussed is to use code generation to provide this dispatch mechanism. The basic advantage is obvious: less code for the bean developer to write. There are other advantages to code generation, and one of them is that the code written for the base class would not need to contemplate derived classes. (The tool could provide this information in a generated layer.) So this might address your objection.

    I will be the first to say that spec support for these concepts would make the bean developers job easier. But the main point is that the EJB spec--in its current form--can work with your existing database schema, even with data model inheritance. With proper tool support (e.g. the XDoclet approach we've been discussing), some of the messiness we're talking about can become an implementation detail.
  15. I am not sure I would agree to this statement:

    "First, entity beans are intended to provide an object-oriented view of information in a persistent store, and inheritance and polymorphism are key
    aspects of the object-oriented programming paradigm"

    I always thought that Entity Beans are more like means to get access to business objects. A business object may have its data spread all over the database or span multiple databases. So Entity Bean is just means to bring all this together under one wrapper...

    I would not say that Entity Beans were "intended to provide an object-oriented view" in a true OO sense.

    What do you think?
    Gennadiy
  16. "I always thought that Entity Beans are more like means to get access to business objects. A business object may have its data spread all over the database or span multiple databases. So Entity Bean is just means to bring all this together under one wrapper..."

    I think you are correct, but so am I. :-)

    Look at 4.1.2 for the EJB 2.0 spec, "Flexible Component Model." There are two bullet points that deal with how entity bean components can be used. The first one is the one you point out, and the second is the one that I did.

    Just to shore up my statement, I'll cite 4.3.2 as well: "A typical entity object has the following characteristics: Provides an object view of data in the database." etc.

    Also, 5.1, Overview, says "For a client, a session object is a non-persistent object that implements some business logic running on the server; an entity bean is a component that represents an object-oriented view of some entities stored in a persistent storage, such as a database, or entities that are implemented by an existing enterprise application."

    The above is almost exactly what I claimed. However, your point of view is a 100% valid approach as well, in my opinion (and the spec's).
  17. I think the key point here is that "an aobject-oriented view" of the database doesnt imply that all concepts related to OO have to be represented. Concepts like abstractions, etc are never represented in the database. An entity bean can only take whats in the database and present it as an object. If there are multiple data entities in the database with relationships, there will be multiple entity beans representing them as object and also their relationships, but these are still data-related relationships.
    I think this is a well-thought out article but i seriously question the need to give an "object-oriented inheritance structure" to entity beans. Now, the article talks about "data inheritance structure". In my opinion, that should be kept separate from OO structure and the data inheritance structure should be implemented in the entity benas in other ways rather than using concepts like class inheritance or delegation.


  18. Daniel,

    Have you looked at how Entity Bean inheritance is implemented by IBM's WSAD? (BTW, you dont need WSAD - you can hand-code this yourself) (sadly WSAD4 is still EJB1.1, but the same principles should apply for EJB2)

    You use standard java inheritance (and polymorphism) on the remote/local interface and the bean implementation classes.
    You have a separate Home for each, and they both share the same PK.

    There are some limitations, in that you have to implement yourself any base-class finder methods (you have to call the individual derived-bean finder methods and aggregate...)

    Unless, I have missed something, it seems that using this approach does away with having to implement the polymorphism yourself... (no?)

    -Nick


  19. <quote>
    There are some limitations, in that you have to implement yourself any base-class finder methods
    </quote>

    How would you do that in EJB QL?

    --
    Cedric


  20. >>How would you do that in EJB QL?

    If I understand your Q, you dont use EJBQL to do the base-class finder - you have to write your own method that delegates to the 'subclassed' Entities.

    The subclassed entities would use EJBQL as per normal (thats where you implement the discriminator if thats what you mean)

    (Not sure I understood your question though.. did I answer it?)

    -Nick
  21. <Nick Minutello>
    Have you looked at how Entity Bean inheritance is implemented by IBM's WSAD? (BTW, you dont need WSAD - you can hand-code this yourself) (sadly WSAD4 is still EJB1.1, but the same principles should apply for EJB2)
    </Nick Minutello>

    XDoclet already does what WSAD (and Visual age before that) does and much much more. You have absolute control over the mechanism but the defaults applied are very elegant. What WSAD and XDoclet do are not about 'data model inheritance' and that's what Dan talks about, the rest (interface/home/pk/etc inheritance) are very easy to handle and XDoclet makes it so easy to do that.

    Ara.
  22. I think that the only real conclusion of this article is that "There is no support for this functionality in the EJB component model".

    IMHO, writting an application with hacking techniques as the ones proposed in this article, is analogous to writting an object-oriented application in the C programming language. Of course you can do it, but it's non-standard, inelegant, unproductive, confusing, unmaintainable, and so on. Also, I think that code generation is only a workaround for this. (In the case of C, a new language had to be created... Is JDO the new creation to overcome Entity Beans limitations?)

    Plus, which are the benefits of "achieving" inheritance in such a way, if you necessarily need the source code of the base class and you have to modify it each time you add or delete a derived class? IMHO, this is a way of effectively losing the benefits of inheritance and polymorphism.

    Finally, I think that the Entity Beans spec is bad conceived from the very beginning, so I would not expect much from it in the future. I would rather expect JDO (or any other well conceived spec) to became the solution in a near future, at least from a theoretically point of view... (Will O/R mapping technologies or object-oriented databases achieve good performance in a near future?)
  23. Adrian, your comments represent an important view in this discussion. However, no one is really debating your main point: implementing virtual function dispatch by hand is less elegant than having EJB container support.

    Please keep in mind that I'm describing a technique to represent a particular class of data schemas with CMP EJBs. You question what the "benefits of 'achieving' inheritance in such a way" are. Primarily, it is to be able to use a data schema that has inheritance. It may be obvious to you and many other experienced developers that "of course you can do it," but I'm pretty sure it isn't obvious to everyone.

    The code generation that we've discussed is a workaround for the lack of support for inheritance in the EJB specification, as you say. But that doesn't make it bad--just less than optimal. Of course it would be nice to have support for this in the spec, but in my opinion, EJBs are designed with tool support in mind anyway. Using a well-designed tool like XDoclet can make all the moving parts of EJBs run smoothly, including (potentially) this one. Just as an aside, it's interesting you mentioned C and its object-oriented successor. I think the first C++ compiler was a C code generator, wasn't it?

    Thanks for presenting your point of view, which I know is shared by others. (I'll leave the EJB vs. JDO debate alone.)
  24. Good stuff. It could be applied in many cases. But generally, I consider it only like a hack, workaround, etc...
    I think, complete inheritence will be achieved when the following EJB QL will work:

    SELECT OBJECT(p) from PartyBean p WHERE p.displayName='Pupkin'

    alex
  25. Very interesting discussion. Hope it's still on?

    According to [Meyer 88], inheritance is supposed to implement the "open/closed" principle, keeping your code open for extension, but with a stable interface for reuse.

    So here's a challenge: devise a scheme that allows a new subclasses to be added **in a different deployment unit**.
    Note that inheritance is not just about late binding of operations, but also about polymorphic typing for references.
    Of course, this may be somewhat difficult, with EJB not even allowing queries to span deployment units.

    If we have to implement inheritance with Xdoclet or some other preprocessor, then after all, the real "components" might be the xdoclet input files, not the Enterprise Beans. So combination of components happens in source code, before compilation and deployment, outside the managed environment of the application server; For example, you will not be able to add a new component to a running system. Also, as a component producer, you will not be able to distribute your components in a binary format.
  26. Gents.
    The inheritance that we need, i think it something like
    Alex Loubyansky write:

    SELECT OBJECT(p) from Employee p WHERE p.firstName='Pupkin'

    The actual beans in the returned Collection are:

    Programmer,
    Manager,
    ChiefManager
    ...

    The Programmer, Manager and ChiefManager are inherite Employee, and override some methods, and other typical object oriented things

    Am i right?

    This thing allow us remove fields such as "user type" and shit such as writing finders with "... WHERE userType=1"
  27. .
  28. Hi!
       Tks for the article
      I tried ur example on BEA Weblogic 61 sp3. Sorry to say it didn't work.
  29. Hmm.. what I can see from this article still doesn't address the problem as I see it.
    The beahviour inheritance in EJBs is something that can be done and is relatively easy. You don't even have to do the "if else" in all methods, just create a "proxy" (which could be flyweight if you really wanted) in the ejbCreate from a afactory using discriminator.
    The hard thing is how do you do real polymorphic relationships?
    That is, if I have a tree structure for example, with leaves being a special class, how can I do it w/o some extra database hits? Especially if my nodes live in two entirely different tables? With raw SQL it's easy.
    I could model the whole tree as one entity bean and do BMP (which would solve my design problem, but not the inheritance), but what if I have (as I do) a lot of "shared" nodes, which I would like to cache? To be more precise, I have one "supertree" with 10,000s of nodes, and then "views", or subtrees with 10s or 100s of nodes.
    Regards,
    Vlad
  30. Ghetto Polymorphism[ Go to top ]

    public String getDisplayName()
    {
      String code = getTypeCode();
      if (code.equals("I"))
        return getPerson().getDisplayName();
      else if (code.equals("C"))
        return getCorporation().getDisplayName();
      throw new EJBException( "Unknown type" );
    }

    You are not really trying to pass this off as polymorphism are you? JDO/Hibernate! Entity Beans are dead.
  31. Containment is not Inheritance[ Go to top ]

    Containment is not Inheritance. These are separate concepts, each having its appropriate use in an OO design.

    Using containment as a workaround for the lack of inheritance in EJBs may be a viable solution if you must use EJBs - but it's still a workaround.

    EJBs do not support inheritance.
  32. sample code does not handle deletion[ Go to top ]

    I found this article to be very interesting and useful. Without really getting in to it, I found that given the intended use of EJBs to represent data in a database that this approach solves the problem of a relationship to an abstract entity that has two of more concrete implementations. Most of the complaints that have been posted are true on a theoretical level, but are not that important given what EJBs are meant for.

    I think it is a very good solution to work around a shortcoming of the spec.

    That said I think the sample code fails to handle the removal of these EJBs. I got this sample code to run on JBoss, but upon creating and then deleting a corporation, the party bean is still left behind. I do not think this will be difficult to fix, though I have not coded a fix, by having the corporation and person beans call remove on their corresponding party bean.

    Thanks for the great article,
    Mark