Extending EJBHome and ValueObjects
From the EJB 2.1 spec (final draft)
10.6.10 (from the spec)
--:: This clause allows inheritance for interfaces ::--
The remote home interface is allowed to have superinterfaces. Use of interface inheritance is subject to the RMI-IIOP rules for the definition of remote interfaces.
--:: And this practically takes it away ::--
The return type for a find<METHOD> method must be the entity bean's remote interface type (for a single-object finder), or a collection thereof (for a multi-object finder).
And here's an example demonstrating an extremely powerful extension to ValueObject pattern:
public interface MyLocalHome extends EJBLocalHome
{
public MyLocalObject create(ValueObject data) throws CreateException;
public MyLocalObject findByPrimaryKey(int pk) throws FinderException;
}
What is so powerful about this? For some applications it makes perfect sense for all EntityBeans to offer these four basic services: create, load, store and delete. Since all these EntityBeans use DAO's to do the actual database magic, they (the entity beans) are - in fact identical!
You need only to create a class which delegates the operations to DAO's and implements the EntityBean interface and then all your Bean implementations just extend this basic class. (We are not extending EJB from EJB, that would be against the spec.)
In order to fully benefit from this pattern, you need to extend the EJB(Local)Home and EJB(Local)Object to offer these methods and design your value objects so that they inherit from common base, maybe just as simple as getId() method and/or maybe some common serialnumber pattern functionality.
Now, whenever you need a new EJB, you just create empty implementation class, home and remote(local) interfaces extending those from the base classes. The only thing you need to actually write is the DAO for the new EJB (and of course the valueobject)
The big question: Is this against the current spec, and if it is, will this change in the future? Remember that we are not inheriting from the EJB's but from ordinary java classes and interfaces and I don't see that this kind of functionality would break anything?!
I've implemented this kind of a system using JBOSS (had to tweak the code a bit to make it work correctly with extended homeinterfaces) but after the "fix" it worked perfectly. Saves me about 300 lines of code/bean.
Please tell me what you think about this. I can post more sample code if this doesn't make any sense.
I see your point. I've used that technique with my valueobjects to implement some interfaces by delegating calls to aggregate objects to do the actual processing.
Here's an example of the things you can accomplish if you use interface inheritance with your ejbs (warning: oversimplified example to keep it short)
List beanList = new ArrayList();
beanList.add("MyBean1");
beanList.add("MyBean2");
beanList.add("MyBean3");
for (Iterator itr = beanList.iterator(); itr.hasNext(); )
{
myBeanHome = (MyBeanHome)initCtx.lookup((String)itr.next());
myBeanHome.doSomeCommonOp();
}
Basically all my entitybeans have zero code in implementation (extended from common class) zero code in home interface (extended from common interface) and zero code in local interface (also extended) But not only that, my session beans are also more simple because the interface to all entity beans is the same.
And BTW: I found proof that this technique is possible JDJ article:
http://www.sys-con.com/java/articlea.cfm?id=1557
and picture:
http://www.sys-con.com/java/picture.cfm?pic=http://www.sys-con.com/java/archives3/0708/musser/fig4.jpg
I'm not a subscriber so I cannot access the article itself, but the picture is quite clear. Two beans one interface...
Hopefully some sun guy would comment about the specification!
More confusion...
From the Developer's guide to Enterprise JavaBeans (Sun One document, version 7 beta)
Location: Using EntityBeans -> Developing Entity Beans -> Providing Interfaces:
-- snip --
The home interface defines the methods that enable a client accessing an
application to create and remove entity objects. A home interface always extends javax.ejb.EJBHome.
-
always extends EJBHome, but must it extend it directly or via some other interface extended from it? If it must extend it directly, could someone with enough knowledge explain why?
first at all, to save lines & lines of code ... the inheritance is the best of solution. With delegation, you will have 2 instances in your JVM for just one reuse, btw a object that inherits (with all inherits relationships you want ...) will have just one instance.
Concerning EJB Home interface inheritance... it's just an interface ... and there is no problem for the interface and reusing. remember that the class that implements the Home interface (create(VO) findByPK()...)is the class who implements SessionBean or EntityBean interface...
read carefully the spec, when there is a call on the EJB Home, the EJB container uses a free instance of the EJB in a pool ( the EJB instance at this moment represents nothing) to invoke one of the Home method
So the inheritance could be use ... but just for reusing. the JNDI couldnt cast with polymorphism a "super" home factory into a "concrete" home factory ... you can just have the concrete ones
ValueObjects are just data structures (Serializable). you can make it extending. do not forget to distribute the bytecode of the value objects on client layer ...
please send me a email if you want the JDJ with the article...
gui at 2007-7-6 1:11:50 >
