An entity bean may have relationships with other entity beans with container-managed persistence (CMP).
Relationships may be one-to-one, one-to-many, or many-to-many relationships.
Container-managed relationships can exist ONLY among entity beans within the same LOCAL relationship scope, as defined by the relationships element in the deployment descriptor. Container-managed relationships (CMR) are defined in terms of the LOCAL interfaces of the related beans.
Relationships may be either bidirectional or unidirectional. If a relationship is bidirectional, it can be navigated in both directions, whereas a unidirectional relationship can be navigated in one direction only.
A unidirectional relationship is implemented with a cmr-field on the entity bean instance from which navigation can take place, and no related cmr-field on the entity bean instance that is the target of the relationship. Unidirectional relationships are typically used when the Bean Provider wishes to restrict the visibility of a relationship.
<relationships> <ejb-relation> <ejb-relation-name> Customer-Address </ejb-relation-name> <ejb-relationship-role> <ejb-relationship-role-name> Customer-has-a-Address </ejb-relationship-role-name> <multiplicity>One</multiplicity> <relationship-role-source> <ejb-name>CustomerEJB</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>homeAddress</cmr-field-name> </cmr-field> </ejb-relationship-role> <ejb-relationship-role> <ejb-relationship-role-name> Address-belongs-to-Customer </ejb-relationship-role-name> <multiplicity>One</multiplicity> <relationship-role-source> <ejb-name>AddressEJB</ejb-name> </relationship-role-source> </ejb-relationship-role> </ejb-relation> </relationships>
An entity bean that DOES NOT have a LOCAL interface can have ONLY unidirectional relationships from itself to other entity beans. The lack of a local interface prevents other entity beans from having a relationship to it.
The bean developer navigates or manipulates relationships by using the get and set accessor methods for the container-managed relationship (CMR) fields and the java.util.Collection API for collection-valued container-managed relationship fields.
<relationships> ... <ejb-relation> <ejb-relation-name> Customer-Phones </ejb-relation-name> <ejb-relationship-role> <ejb-relationship-role-name> Customer-has-many-Phone-numbers </ejb-relationship-role-name> <multiplicity>One</multiplicity> <relationship-role-source> <ejb-name>CustomerEJB</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>phoneNumbers</cmr-field-name> <cmr-field-type>java.util.Collection</cmr-field-type> </cmr-field> </ejb-relationship-role> <ejb-relationship-role> <ejb-relationship-role-name> Phone-belongs-to-Customer </ejb-relationship-role-name> <multiplicity>Many</multiplicity> <relationship-role-source> <ejb-name>PhoneEJB</ejb-name> </relationship-role-source> </ejb-relationship-role> </ejb-relation> ... </relationships>
public abstract class CustomerBean implements javax.ejb.EntityBean { ... public void addPhoneNumber(String number, byte type) throws NamingException, CreateException { InitialContext jndiEnc = new InitialContext(); PhoneHomeLocal phoneHome = (PhoneHomeLocal) (jndiEnc.lookup("PhoneHomeLocal")); PhoneLocal phone = phoneHome.create(number,type); Collection phoneNumbers = this.getPhoneNumbers(); phoneNumbers.add(phone); } public void removePhoneNumber(byte typeToRemove) { Collection phoneNumbers = this.getPhoneNumbers(); Iterator iterator = phoneNumbers.iterator(); while(iterator.hasNext()){ PhoneLocal phone = (PhoneLocal)iterator.next(); if (phone.getType() == typeToRemove) { phoneNumbers.remove(phone); break; } } } public abstract java.util.Collection getPhoneNumbers( ); public abstract void setPhoneNumbers(java.util.Collection phones); }
The bean provider MUST consider the type and cardinality of relationships when the entity bean classes are programmed. The get method for a cmr-field MUST return either the local interface of the entity bean or a collection (either java.util.Collection or java.util.Set) of the same. The set method for the relationship MUST take as an argument the entity bean’s local interface or a collection of the same.
public abstract class CustomerBean implements javax.ejb.EntityBean { ... // persistent relationships public abstract AddressLocal getHomeAddress(); public abstract void setHomeAddress(AddressLocal address); public abstract AddressLocal getBillingAddress(); public abstract void setBillingAddress(AddressLocal address); public abstract CreditCardLocal getCreditCard(); public abstract void setCreditCard(CreditCardLocal card); public abstract java.util.Collection getPhoneNumbers( ); public abstract void setPhoneNumbers(java.util.Collection phones); ... }
The Bean Provider can specify the removal of an entity object in two ways:
By the use of a remove method on the entity bean’s COMPONENT interface or HOME interface.
By the use of a cascade-delete specification in the deployment descriptor (ONLY when other member of relationship has multiplicity ONE).
When the remove() method is invoked on an entity object, the container MUST invoke the entity Bean Provider’s ejbRemove() method. After the bean provider’s ejbRemove() method returns (and prior to returning to the client), the Container MUST remove the entity object from all relationships in which it participates, and THEN remove its persistent representation.
Once an entity has been removed from a relationship, the accessor methods for any relationships to the entity will reflect this removal. An accessor method for a one-to-one or many-to-one relationship to the entity will return null; and an accessor method for a many-to-many relationship to the entity will return a collection from which the entity object has been removed.
The Container MUST detect any subsequent attempt to invoke an accessor method on the removed entity object and throw the java.rmi.NoSuchObjectException if the client is a REMOTE client or the javax.ejb.NoSuchObjectLocalException if the client is a LOCAL client. The Container MUST detect an attempt to assign a removed entity object as the value of a cmr-field of another object (whether as an argument to a set accessor method or as an argument to a method of the java.util.Collection API) and throw the java.lang.IllegalArgumentException.
After removing the entity object from all relationships and removing its persistent representation, the Container MUST then cascade the removal to all entity beans with which the entity had been previously in container-managed relationships for which the cascade-delete option was specified. The remove method, alone, causes only the entity on which it is invoked to be removed. It DOES NOT cause the deletion to be cascaded to other entity objects. In order for the deletion of one entity object to be automatically cascaded to another, the cascade-delete mechanism should be used.
The cascade-delete deployment descriptor element is used within a particular relationship to specify that the lifetime of one or more entity objects is dependent upon the lifetime of another entity object.
<ejb-relation> <ejb-relation-name>Customer-HomeAddress</ejb-relation-name> <ejb-relationship-role> <ejb-relationship-role-name> Customer-has-a-Address </ejb-relationship-role-name> <multiplicity>One</multiplicity> <relationship-role-source> <ejb-name>CustomerEJB</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>homeAddress</cmr-field-name> </cmr-field> </ejb-relationship-role> <ejb-relationship-role> <ejb-relationship-role-name> Address-belongs-to-Customer </ejb-relationship-role-name> <multiplicity>One</multiplicity> <cascade-delete/> <relationship-role-source> <ejb-name>AddressEJB</ejb-name> </relationship-role-source> </ejb-relationship-role> </ejb-relation>
The cascade-delete deployment descriptor element is contained within the ejb-relationship-role element. The cascade-delete element can ONLY be specified for an ejb-relationship-role element contained in an ejb-relation element if the other ejb-relationship-role element in the same ejb-relation element specifies a multiplicity of ONE. The cascade-delete option CANNOT be specified for a many-to-many relationship. The deletion of one entity object can only be cascaded to cause the deletion of other entity objects if the first entity object is in a one-to-one or one-to-many relationship with those other entity objects.
Visit http://java.boot.by for the updates.