Managing Relationships

   

There are some interesting semantics concerning how relationships between entity beans are maintained . First of all, it should be clear by now that the only ways to update a relationship defined by a CMR field are to use the associated set method or operate on the collection returned by the get method. What's interesting to look at is that the behavior of a CMR field set method is different depending on the multiplicity of the relationship.

In the case of a one-to-many relationship, an entity object that is one of the targets of the relationship can, by definition, only be associated with a single source entity. For example, a one-to-many relationship between a CustomerBean and an OrderBean implies that an order is related to one and only one customer. If an order needed to be reassigned to another customer for some reason, its relationship to the initial customer should be removed. Consider the following code segment:

 Customer purchasingAgent = ...  Customer recipient = ...  // transfer the orders placed by a purchasing  // agent to the recipient of the orders  Collection orders = recipient.getOrders();  orders.add(purchasingAgent.getOrders());  recipient.setOrders(orders); 

You might think that the preceding code needs to include a statement that removes the orders from the purchasingAgent , but the container does that part for you. Because this is a one-to-many relationship, assigning a collection of Order objects to one Customer implies that those Order objects must be removed from any other Customer to which they might be assigned. This is the only way referential integrity can be preserved. Also important here is that the collection object that holds the Order objects associated with a Customer isn't being reassigned ”the Order objects are instead being cleared from one collection and added to the other.

A one-to-one relationship is similar to a one-to-many in that a target object in the relationship can only belong to a single entity. Whenever a set method is called to assign the target of a one-to-one relationship, the object being assigned is removed from any other object it's assigned to under the same relationship. A many-to-many relationship is handled similarly to a one-to-many in that the collection associated with an entity isn't changed when a set method is called, only the contents of the collection are. What's different here is that the entity objects aren't removed from any existing relationships when a new assignment is made.

The way collections are used with managed relationships might seem somewhat strange at first. Normally, you would expect a set method that accepts a Collection parameter to assign the argument it receives to the corresponding Collection reference. With CMP, the container always creates the collections associated with CMR fields, and they aren't replaced when you call set methods that manipulate them. The container's implementation of such a set method transfers the contents of the Collection argument, but doesn't assign it directly. The collection objects you instantiate are never used by the container to maintain a relationship. However, if you pass a null or a collection that doesn't include objects of the expected type to a CMR set method, you'll get an IllegalArgumentException .

The behavior of one-to-many CMR fields when an object is reassigned can cause a problem when you're iterating a collection if you're not careful. The only correct way to remove an element while iterating a collection that's part of a container-managed relationship is to use the remove method of Iterator . If a statement is executed that transfers an object out of the collection without first calling remove , an IllegalStateException is thrown. The following code segment uses the purchasing agent example again to show the correct way to transfer an object out of a collection that's being iterated:

 Customer purchasingAgent = ...  Customer recipient = ...  // transfer the orders placed by a purchasing  // agent to the recipient of the orders  Iterator iter = purchasingAgent.getOrders().iterator();  while (iter.hasNext()) {   Order o = (Order)iter.next();    // have to include the following line to make this safe    iter.remove();    recipient.add(o);  } 

Note

The interfaces in the Java collection framework include some methods that are designated as optional. A class can implement such an interface and simply throw an UnsupportedOperationException for methods it chooses to not allow. The remove method of Iterator is one of these optional methods. Because of the requirement for transferring objects out of a managed relationship collection, the container must use collection classes whose iterators support remove .


Whenever an entity object is deleted as the result of a call to remove (or a cascade deletion that follows ), the container does whatever is necessary to remove the entity from any relationships. If an entity that is the target of a one-to-one or one-to-many relationship is deleted, the get method for that relationship will return null . Similarly, the collection returned for a one-to-many or many-to-many relationship that once held the entity will no longer include it.

An important subject to you when you consider how the container manages relationships is that of referential integrity. As long as you manipulate assignments using the methods of Collection and Set and follow the rule of using remove for an Iterator , you don't have to worry about maintaining the referential integrity of your data. If you declare all your relationships in the deployment descriptor and apply cascade-delete wherever it's appropriate, the container is responsible for maintaining referential integrity for you.



Special Edition Using Enterprise JavaBeans 2.0
Special Edition Using Enterprise JavaBeans 2.0
ISBN: 0789725673
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net