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
recalculate
did not see change made by setter on entity ejb. - Finding entity bean again after
recalculate
does not see the changes made by that method. For examplevalueUpdatedX
is 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
findByPrimaryKey
takes data from EJB cache instead of reload it from datasource. - I tried to use different finder with
include-updates
but with same effect. - Removing fetching entity
e
and fetching onlyentityUpdated
works 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
.