At page 396 in Head first EJB the relationship field for director is set in the ejbPostMethod:
... InitialContext ctx = new InitialContext(); DirectorHome dirHome = (DirectorHome) ctx.lookup("java:comp/env/ejb/DirectorHome"); Director dir = home.findByPrimaryKey(directorID); setDirector(dir); ...
Why do we need to set the relationship field by hand. shouldn't that be taken care of by the container in a CMP? Another question. Do we need to declare the relationship fields in the local component interface in an CMP? Thank you everyone /Magnus
Setting aside the more general (justified) question of 'couldn't CMR have been spec'd to be more convenient during object creation?', I think the problem is 'what can I depend upon at each stage of entity creation?'. I think the most fundamental issue is that until ejbCreate completes, the container doesn't know the PK. Since it doesn't know the PK, there is really only one situation where it could successfully initialize a relationship: a 1-1 mapping that was only navigable from your current bean to the related bean, but not vice versa. Any other form of mapping would require the container to do something with the PK of the current bean, and it doesn't know it yet. By the time you get to ejbPostCreate, the container knows the PK.
Thank you Reid, your answers are always very good. Do know if it is required to declare the relationship fields in the local component interface in an CMP, in order for the relationship to work? I can't seem to find the answer for that. Best Regards /Magnus
I can't quote chapter and verse (which means I'm going to need to learn something I don't know yet!). I can relate some tidbits that would cause me to draw some tentative conclusions: 1. CMR aside, *any* field needs both an abstract accessor and an abstract mutator declared on the bean class. 2. For non-CMR fields, I've found that those accessors/mutators don't need to be declared in a local or remote interface. This is a good thing, because I don't think it makes sense to mutate a primary key field! 3. If you don't declare the CMR field on a local or remote interface, then your Java code would not be able to navigate from one bean to the other. 4. I'm pretty sure that EJB-QL navigation from bean to bean is determined completely by the descriptor, but I haven't verified this. 5. Unlike with the primary key for the current bean, I don't think you declare the foreign-key fields (the PK fields for the bean related via CMR) anywhere. Obviously the datatabase table must contain those columns, but guess how the mapping is done must always depend upon the vendor-specific mechanism (typically an additional descriptor file). In the Java code and ejb-jar.xml file all you do is deal with a single field for the related object. So, adding all that up I would guess you don't have to declare the relationship field in the local component interface. You'd generally want to (or you probably wouldn't have bothered with CMR), but you don't have to. For example I strongly suspect you could just provide an accessor if you didn't want a client to change the relationship. Also remember that all bets are off with remote component interfaces - no access to CMR fields.
Originally posted by Vish Kumar: Niether CMR nor CMP fields are to be specifed in the component interface.
I don't think this is correct. I've written code with CMP fields in both types of component interfaces. CMR fields only work with local interfaces. Logically, if you couldn't ever access *any* fields through *any* of the interfaces, then entity beans could only provide business methods... and you don't usually put many business methods on an entity bean. Typically that is the purpose of session beans.
I am confused. "Do know if it is required to declare the relationship fields in the local component interface in an CMP, in order for the relationship to work? " - My answer is NO. We declare the relationship fields in the DD, not in the component interface of an entity bean. We may/may not expose the accessor/mutator methods for the relationship fields in the local component interface.
If I understand you correctly the container only uses the abstract schema declared in the deployment descriptor and the abstract accessor declarations in the bean class to implement the relationships between entity beans. Thank you Vish and Reid for your help /Magnus