I am working with following code, with mixed EJB 2.1 entity beans and JDBC operations done in a single container-managed transactions in Weblogic WLS 11g:
Entity e = entityHome.findByPrimaryKey(entityId);
e.setFieldX(initalValueX);
// this performs complex analysis of data fetched by JDBC
// and performs update of row in database corresponding with entity e.
// Let say it sets newValueX on field X
recalculate(entityId, newValueX);
Entity entityUpdated = entityHome.findByPrimaryKey(entityId);
Object valueUpdatedX = entityUpdated.getFieldX();
I encountered here two problems:
- Method
recalculatedid not see change made by setter on entity ejb. - Finding entity bean again after
recalculatedoes not see the changes made by that method. For examplevalueUpdatedXis equal toinitialValueX, but should be equal tonewValueX.
I managed to solve problem 1. by adding a dummy finder before calling recalculate. Here is an annotation for that finder:
@ejb.finder
signature="java.util.Collection findFlushEJBCache()"
type="remote"
@wls.finder
signature="java.util.Collection findFlushEJBCache()"
load-state="True"
where-clause="0=1"
include-updates="true"
finder-sql="SELECT ID FROM entity WHERE 0=1"
The trick is the include-updates flag. WLS documentation says it is a way to ensure that all changes on currently used beans are sent to underlying datasource. So I do:
Entity e = entityHome.findByPrimaryKey(entityId);
e.setFieldX(initalValueX);
entityHome.findFlushEJBCache();
recalculate(entityId, newValueX);
And method recalculate sees new value of field X.
How can I solve problem 2? How to force WLS to reload the entity from underlying datasource to fetch fresh data, without rewriting recalculate method to use EJBs? How to tell WLS that given entity should be removed from cache (invalidated)?
Some research I already done on the subject:
- I think the root cause is that finder
findByPrimaryKeytakes data from EJB cache instead of reload it from datasource. - I tried to use different finder with
include-updatesbut with same effect. - Removing fetching entity
eand fetching onlyentityUpdatedworks and gets fresh data. Probably because there is nothing in cache, so data is retrieved from datasource. But this is unacceptable - I need operations on EJB both before and afterrecalculate.