1

我正在使用以下代码,混合 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();

我在这里遇到了两个问题:

  1. 方法recalculate没有看到 setter 对实体 ejb 所做的更改。
  2. 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 应该从缓存中删除给定的实体(无效)?

我已经对这个主题进行了一些研究:

  • 我认为根本原因是finderfindByPrimaryKey从EJB缓存中获取数据,而不是从数据源重新加载。
  • 我尝试使用不同的取景器,include-updates但效果相同。
  • 删除获取实体e并获取仅entityUpdated有效并获取新数据。可能是因为缓存中没有任何内容,所以从数据源中检索数据。但这是不可接受的——我需要在 EJB 之前和之后都进行操作recalculate
4

0 回答 0