实体对象缓存
实体对象一旦创建,BC4J就会存储视图对象到一个特殊的事务缓存,有很多原因我们需要这么做,这在JDeveloper BC4J文档中有全面的描述。两个重要的好处是:
l 同一个根应用模块中的多个视图对象可以共享相同的潜在的实体对象。那意味着对一个视图对象上做的修改就可以立即对其它引用修改后实体对象的视图对象可见。
l 未保存的修改保存在缓存中,即使视图的行被刷新了。比如,在主/明细关系中,明细视图对象上实体继承的属性值保存在缓存里,即使用户从主记录行导航到明细行。所有你的未保存的修改在事务的生命周期保持不变。
理解了缓存存在很重要,因为你必须明确和它交互来做特定验证,比如,当做一个唯一性验证,你必须即啊要在实体缓存和也要在数据库中查找重复数据。
这里有三种主要方式来即在缓存也在数据库里检查数据。
1. 调用findByPrimaryKey()方法
2. 手工遍历缓存.
3. 使用关联遍历缓存
findByPrimaryKey()方法
findByPrimaryKey()方法保证了先从缓存中查找匹配给定的键值和实体对象类型,然后才查找数据库。这是一个非常有用的方法,但是如果你想使用的轻量级的方法,那它就不是你要找的的了,因为它会实例化在数据库中找到的所有匹配的实体对象。它也会把整个实体对象拉入到内存中,而不仅仅是键值。尽管如此,这个方法可以―而且应该―用于你不期望找到匹配结果的情形,比如,当验证序列号生成的主键时。当你需要调用一个方法来访问中间层来查找匹配的时候使用这个方法也是合适的。
oracle.apps.fnd.framework.toolbox.schema.sever.SupplierEOImpl中下面的代码演示了如何使用这个方法:
public void setSupplierId(Number value)
{
if (value != null)
{
// Supplier id must be unique. To verify this, you must check both the
// entity cache and the database. In this case, it's appropriate
// to use findByPrimaryKey( ) because you're unlikely to get a match, and
// and are therefore unlikely to pull a bunch of large objects into memory.
// Note that findByPrimaryKey() is guaranteed to check all suppliers.
// First it checks the entity cache, then it checks the database.
OADBTransaction transaction = getOADBTransaction();
Object[] supplierKey = {value};
EntityDefImpl supplierDefinition = SupplierEOImpl.getDefinitionObject();
SupplierEOImpl supplier =
(SupplierEOImpl)supplierDefinition.findByPrimaryKey(transaction, new Key(supplierKey));
if (supplier != null)
{
throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT,
getEntityDef().getFullName(), // EO name
getPrimaryKey(), // EO PK
"SupplierId", // Attribute Name
value, // Bad attribute value
"ICX", // Message application short name
"FWK_TBX_T_SUP_ID_UNIQUE"); // Message name
}
}
setAttributeInternal(SUPPLIERID, value);
} // end setSupplierId()
手工迭代缓存
你可以手工检查实体对象缓存来做可以做findByPrimaryK