我正在使用以下代码,混合 EJB 2.1 实体 bean 和 JDBC 操作在 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();
我在这里遇到了两个问题:
- 方法
recalculate
没有看到 setter 对实体 ejb 所做的更改。 recalculate
在没有看到该方法所做的更改之后再次查找实体 bean 。例如valueUpdatedX
等于initialValueX
,但应该等于newValueX
。
我设法通过在调用之前添加一个虚拟查找器来解决问题 1 recalculate
. 这是该查找器的注释:
@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"
诀窍是include-updates
国旗。WLS 文档说这是一种确保将当前使用的 bean 上的所有更改发送到底层数据源的方法。所以我这样做:
Entity e = entityHome.findByPrimaryKey(entityId);
e.setFieldX(initalValueX);
entityHome.findFlushEJBCache();
recalculate(entityId, newValueX);
并且方法recalculate
看到字段 X 的新值。
如何解决问题 2?如何强制 WLS 从底层数据源重新加载实体以获取新数据,而不重写recalculate
使用 EJB 的方法?如何告诉 WLS 应该从缓存中删除给定的实体(无效)?
我已经对这个主题进行了一些研究:
- 我认为根本原因是finder
findByPrimaryKey
从EJB缓存中获取数据,而不是从数据源重新加载。 - 我尝试使用不同的取景器,
include-updates
但效果相同。 - 删除获取实体
e
并获取仅entityUpdated
有效并获取新数据。可能是因为缓存中没有任何内容,所以从数据源中检索数据。但这是不可接受的——我需要在 EJB 之前和之后都进行操作recalculate
。