Capturing the Handle of a related entity during the ejbCreate method of a containing entity.

ARCHITECT'S CORNER
Entity bean relationships in EJB 1.1
Grant Holland
Listing 1. Capturing the Handle of a related entity during the ejbCreate method of a containing entity.

This example improves upon example 2 of Part 1 by replacing the related key String “productName” by the byte array (byte[]) productSerHandle, which contains the serialized Handle of the related Product entity. This Handle will be persisted to the database, rather than the String productName.


public LineItemPK ejbCreate (
		int		lineItemID,
		int		orderID,
		int		quantity,
		Product	product	)

    throws CreateException,RemoteException
{
LineItemPK pk;

    try
    {
	  // capture all 3 field types
	  this.lineItemID = lineItemID;	// persistent data
	  this.orderID = orderID;		     // persistent data
	  this.quantity = quantity;	    // persistent data
	  this.product = product;		   // related EJB object
	  this.productName = 		       // related key
		((ProductPK)product.getPrimaryKey()).productName;

     // serialize the Handle
     byte[] productSerHandle = serialize(product.getHandle( ));

	 /*
	 // persist persistent data
	 < write “lineItemID” 	     to persistent store >
	 < write “orderID” 		to persistent store >
	 < write “quantity”   	     to persistent store >
	
	 // persist related key
	 < write “ productSerhandle”   to persistent store >
	 */

	 // create and initialize Primary Key object
	 LineItemPK pk = new LineItemPK(); 	// make PK
	 pk.lineItemID = lineItemID;		         // capture identity field
	 pk. orderID = orderID;			       // capture identity field
   }
    catch(Exception e)
  {
	throw new CreateException(e.getMessage());
  }

    return pk;
}

byte[] serialize( Handle hndl )throws IOException
{
    ByteArrayOutputStream bs = new ByteArrayOutputStream();
    ObjectOutputStream os = new ObjectOutputStream(bs);
    os.writeObject( hndl );
    return bs.toByteArray();
}
The advantage of saving the Handle of the product entity comes in the ejbActivate() method, which can directly reconstitute the related Product EJB object via the getEJBObject() method call on the deserialized Handle. There is no longer any need to call JNDI to obtain the Home interface to the related entity, nor to call any create of finder methods to obtain the related EJBObject.


public void ejbActivate() throws RemoteException
{
    // get containing entity’s primary key from EntityContext
    LineItemPK lineItemPK = entityContext.getPrimaryKey();

    // get key from PK
    lineItemID = lineItemPK.lineItemID;
    orderID = pk.orderID;

    // use key to read persistent data and related key
    < read persistent data from persistent store >

    < read related key “productserhandle” from persistent store >
    byte[]productSerHandle
            = resultSet.getByteArray(“productserhandle”);

    // deserialize the Handle and use it to
    // reconstitute the related EJBObject
    Handle prodHandle = deserialize(productSerHandle);
    product = (Product)prodHandle.getEJBObject();
}

Handle deserialize( byte[] serHandle )
        throws IOException, ClassNotFoundException
{
ByteArrayInputStream is = new ByteArrayInputStream( serHandle );
ObjectInputStream os = new ObjectInputStream (is);
return (Handle)os.readObject();
}