This article describe the most efficient way to remove a Container-Managed
Persistence (CMP) instance from the option A pool. First, add a method to
your Container-Managed Persistence (CMP) bean.
public void invalidateFromCache()
{
}
Add this method to the CMP local interface. Modify the descriptor
for the method so that it uses TX_REQUIRED.
You can do this using the
EJB descriptor editor by clicking on the assembly tab and then click the
Add button
on the container transactions panel. Select the CMP, then click the invalidateFromCache
method. Select Required from the combo box, then click
OK. You should
then see for example, error! Reference source not found. Next, add a home
method like the one following:
public void ejbHomeInvalidateCompleteOrders(Collection/*<orderlocal>*/ orders)
{
Iterator iter = orders.iterator();
while(iter.hasNext())
{
OrderLocal order = (OrderLocal)iter.next();
// this just adds the option A bean to this transaction so that when
we rollback below
// it gets discarded, i.e. removed from the cache.
order.invalidateFromCache();
}
myEntityCtx.setRollbackOnly();
}
Add this method to the bean's local home by right clicking on
the method, select Enterprise Beans and then promote to local home. Set this
method transaction attribute to RequiresNew also using the same approach as
before. This method takes a List of OrderLocal (our CMP is called Order) and
removes them from the option A cache. Note, that we could have taken a List
of keys but then you would need to execute a findByPrimaryKey and then call
the method. This is more expensive than the approach taken here. The method
basically iterates over the list and calls the invalidate method on each order
in the list. The invalidate method associates the option A bean with the current
transaction. After each bean is associated with the transaction, we mark it
as roll back only. When the method returns, the transaction is rolled back
and all the associated option A beans are discarded from the cache. Business
logic accepts a new order. As part of accepting a new order, it is possible
that several other orders can be completed. The acceptOrder method returns
a List<
OrderLocal> to the caller. The caller must then pass this
list to the home method above to remove them from the cache. They are not
deleted from the database, just the cache. Following is an example:
BookLocal book = ivBookHome.findByPrimaryKey(ivOrder.getSymbol());
Collection/*<OrderKey>*/ completedOrders =
book.acceptOrder(session, pub, ivOrder, cache);
// invalidate all completed orders from the CMP option A cache.
try
{
if(!completedOrders.isEmpty())
ivOrderHome.invalidateCompleteOrders(completedOrders);
}
catch(Exception e)
{
// ignore expected exception
}
This shows looking up a Book CMP, calling its accept order method.
This method returns the orders that need to be removed from the cache as a
result of the call. The acceptOrder method uses a RequiresNew transaction
so its transaction is committed automatically when this method returns. You
then use the home method on Order to remove the returned CMPs from the cache.
The acceptOrder method collects all the Order instances that need to be removed:
public Collection/*<OrderLocal>*/ acceptOrder(…)
Collection completeOrders = new LinkedList();
OrderLocal buyer = ...;
OrderLocal seller = ...;
... some business logic....
if(buyer.getIsComplete())
completeOrders.add(buyer);
if(seller.getIsComplete())
completeOrders.add(seller);
…
return completedOrders;
}
This code demonstrates the application removing a cached object
that it has finished processing. If the application did not do this, then
the cache has both useful and useless instances in it. The useful ones are
records that it still needs or are pending or not completed. There is no point
in caching completed records. An application can use this approach to remove
completed objects.