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.