首页 > 代码库 > EBS OAF开发中实体对象和视图对象的属性设置器

EBS OAF开发中实体对象和视图对象的属性设置器

EBS OAF开发中实体对象和视图对象的属性设置器

(版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处;否则请与本人联系,违者必究)

源文:

Home > Oracle Application Framework Documentation Set, Release 12.2 > Oracle Application Framework Developer‘s Guide > Chapter 5: Implementing Server-Side Features > Entity Object and View Object Attribute Setters


概览

oracle.apps.fnd.framework.server.OAEntityImploracle.apps.fnd.framework.server.OAViewRowImpl类中有很多方法使你在编程的时候为实体对象和视图对象设置属性值。这篇文档解释了每个可行的选项并在不同的情景下建议合适的使用。

注意:这里不解释如何声明式设置实体对象和视图对象的属性值。可以参考Defaulting in Implementing the View

内容

这篇文档根据属性缓存的地方组织为两个主要的部分:

l  缓存在视图对象上属性值

l  缓存在实体对象上的属性值

阅读前提.

l  Java实体对象

l  视图对象的详细介绍-视图对象的属性类型和缓存(了解不同的视图对象属性类型)

缓存在视图对象上的属性值

方法概观

对于存储在视图对象层的属性(它们不映射到实体对象属性),你可以使用下面OAViewRowImpl中方法来设置属性值。

方法1:基本设置器-setAttribute()

1. setAttribute(String name, Object val)
2. setAttribute(int index, Object val)

这两个方法会执行你为它们定义的所有编程验证,然后在super.setAttribute()中,它们使用查找机制来查找并调用相关的set<AttributeName>()方法(注意,你必须在你的代码之后调用super.setAttribute())。

3. set<AttributeName>() //Attribute setter in OAViewRowImpl subclass

这个方法会执行你为这个方法定义的所有编程验证,然后调用方法setAttributeInternal()。注意,你必须在你的代码之后调用setAttributeInternal()方法。

这三个方法会标记依赖的视图对象的查询集合为”脏”状态(你调用它们之后,方法OAViewObjectImpl.isDirty()会返回true).关于isDirty()检查的更多信息请参考Advanced View Object DevelopmentTopics -> Entity Event Notification。

方法2:setAttributeInternal( )

1. setAttributeInternal(int index, Object val)

这个方法会执行所有在视图对象XML文件中为视图对象属性指定的所有声明式验证。和

setAttribute()方法一样,这个方法也会把依赖的视图对象的查询集合标记为”脏”状态。

因为这个方法只执行声明式验证,你不应该覆盖它(你不需要这么做,因为它不应该包含编程式验证);你应该根据需要简单的调用它。

方法3:"Populate" Methods

1. populateAttribute(int index, Objectvalue)
2. populateAttributeAsChanged(int index, Object value)

这些方法会为属性设置值,但是不会执行任何验证也不会影响视图对象查询集合的”脏”标记。

你不要覆盖这个方法并往populate* 方法加入编程验证代码,因为这些方法就是用于简单为属性设置值。

注意:对于实体对象层属性,populateAttributeAsChanged(intindex, Object value)方法的行为不同;参考下面的“缓存在实体对象上的属性值”部分。

下面是一个自定义视图行的示例演示了如何使用这个方法设置表的选择器的值而不影响视图对象的状态。

public void setSelectFlag(String value)
{ 

//Do not call setAttributeInternal as usual in this method. 
// setAttributeInternal(SELECTFLAG, value); populateAttribute(SELECTFLAG, value); 

} 


行为汇总

l  set*方法会执行验证并标记视图对象的查询集合”脏”状态。populate*方法简单设置值而不进行任何验证也不改变视图对象的状态。

使用便条

使用基本设置(选项1)应该作为使用规则,除非你有下面的特殊情形:

l  如果你需要忽略编程验证并仅调用声明式验证,那么你需要使用来setAttributeInternal(intindex, Object val)代替。

l  设置一个属性值而不触发验证或者不影响视图对象的查询集合的”脏”状态,要使用populateAttribute(intindex, Object value)方法.比如,像上面演示的,你可能覆盖一个table bean的”选择器”属性的设置器方法来使用populateAttribute()方法。这允许你存储特定的UI状态而不改变VO的状态。关于“selector”的更多信息,可参考Tables - Classic and Tables - Advanced

注意:一定不要使用populate*方法来设置主键属性值(这对组合关系可能有不利后果)。应为主键属性使用基本的设置器。

 

缓存在实体对象上的属性值

对于存储在实体对象层的属性(它们不映射到实体对象属性),你可以使用下面OAEntityImpl中方法来设置属性值。

注意:在大多数情况下,你通常调用类OAViewObjectImplOAViewRowImpl上上面描述的方法来设置实体对象的值(VO方法最终代理潜在的实体对象方法)。当在你的OAEntityImpl子类中写代码时,但是,你可以调用下面的方法来直接设置实体属性值。

当你调用一个实体对象的比如set<AttributeName>()方法时,你的调用会影响下面的实体对象状态:

l  验证状态(Validationstate)-可通过调用来OAEntityImpl.isValid()检查

l  提交状态(Poststate)- 可通过调用来OAEntityImpl. getPostState ()检查

l  事务状态(Transactionstate)可通过调用来OAEntityImpl. getEntityState ()检查

因为BC4J为实体对象维护这些额外的状态(此外,为视图对象维护的基础的”脏”状态), OAEntityImpl方法细粒度控制如何设置属性值。

方法概观

方法1:基本设置器-setAttribute()

1. setAttribute(String name, Object val)
2. setAttribute(int index, Object val

这两个方法会执行你为它们定义的所有编程验证,然后在super.setAttribute()中,它们使用查找机制来查找并调用相关的set<AttributeName>()方法(注意,你必须在你的代码之后调用super.setAttribute())。

3. set<AttributeName>() //Attribute setter in OAEntityImpl subclass

这个方法会执行你为这个方法定义的所有编程验证,然后调用方法setAttributeInternal()。注意,你必须在你的代码之后调用setAttributeInternal()方法。

这三个方法会标记实体对象为无效状态并根据需要更改实体对象的提交状态和事务状态为STATUS_NEW或者STATUS_MODIFIED,以便BC4J知道实体对象有未提交的修改。

最后,这三个方法也会标记依赖的视图对象的查询集合为”脏”状态。(你调用它们之后,方法OAViewObjectImpl.isDirty()会返回true)

方法2:setAttributeInternal( )

1. setAttributeInternal(int index, Object val)

这个方法会执行所有在视图对象XML文件中为实体对象属性指定的所有声明式验证。和

setAttribute()方法一样,这个方法也会把依赖的实体对象标记为无效状态,改变提交状态和事务状态,也标记依赖的视图对象的查询集合为”脏”状态。

因为这个方法是用来只执行声明式验证,你不应该覆盖它(你不需要这么做,因为它不应该包含编程式验证);你应该根据需要简单的调用它。

方法3:"Populate" Methods

在看每个单独的方法之前,来看一下在大多数populate*方法中可以使用的参数的描述。

Method Parameter

Description

sendNotification

控制是否把实体属性值的改变事件广播给依赖的视图对象。改变事件会运行视图对象查询集合的状态(“脏”标记) .更多信息可参考 Advanced View Object Development Topics -> Entity Event Notification

markAsChanged

当这个参数设置为true时,这个属性被标记为已改变. 

  • BC4J DML阶段期间会提交已更改的持久属性,但是仅仅当实体对象的提交状态为 STATUS_NEW 或者 STATUS_MODIFIED ,因而插入一条心数据或者调用下面的方法来更改属性值setAttribute(), setAttributeInternal()set<AttributeName>()

saveOriginal

控制BC4J是否在更改值之前保存原先从数据库中取到的值到额外的地方.

如果你想保存原先的值:

  • BC4J 比较原先的值和数据库里列上的值(加锁)来检测值是不是过期了.
  • BC4J 保存原先的值当提交失败时,在用户改正验证错误之后这些动作可以再次尝试.

如果原先的值没有保存,那么当前的属性值会被BC4J用来做这些操作.

1. populateAttribute(int index, Objectvalue)

这个方法的行为和下面的调用是一样的:

 populateAttribute(index, value,
                  
false,  // sendNotification
                   false,  // markAsChanged
                   false);// saveOriginal

 

2. populateAttributeAsChanged(int index,Object value)

这个方法的行为和下面的调用是一样的:

 populateAttribute(index, value,

false, // sendNotification

true, // markAsChanged

false);// saveOriginal

3. populateAttribute(int index, Objectvalue,
                    
booleansendNotification,
                     BooleanmarkAsChanged)

这个方法已经不建议使用了.它调用了populateAttribute(index, value, sendNotification,markAsChanged, false).

4. populateAttribute(int index, Object value,
                    
BooleansendNotification,
                     BooleanmarkAsChanged,
                     BooleansaveOriginal)

l  你不应该覆盖这些方法并添加编程验证逻辑,因为这些方法都是用来简单设置属性值的。

l  这些方法不会影响实体对象的验证状态,提交状态或者事务状态。

l  视图对象的查询集合的”脏”标记可通过sendNotification标记值来影响。

建议的参数值

l  对于OAF应用,设置sendNotification为false因此视图对象的查询集合的脏标记不会被你的修改而影响。当视图对象的查询集合变脏,表中类似排序操作都是不允许的(更多信息可参考Tables - Classic and Tables - Advanced)。

l  设置markAsChanged为true,如果你想提交属性值和其它用户修改在DML期间提交到数据库的话。

l  如果你设置markAsChanged为true的话,就设置saveOriginal为true.作为规则,帮助合适的加锁和处理提交失败,如果你计划提交修改的属性值到数据库,saveOriginal参数应该设置为true.

行为汇总

l  set*方法会执行验证并标记实体对象为无效状态,改变实体对象的提交状态,改变实体对象的事务状态,并标记视图对象的查询集合为脏状态。

l  populate*方法简单设置值而不进行任何验证也不改变实体对象的状态。但是,视图对象的查询集合状态(包含脏标记)受sendNotification参数值的影响。

使用便条

使用基本设置(选项1)应该作为使用规则,除非你有下面的特殊情形:

l  如果你需要忽略编程验证并仅调用声明式验证,那么你需要使用来setAttributeInternal(intindex, Object val)代替。

l  为实体对象使用populate*方法是不鼓励的。虽然那么说,但是,也有一些例外的情况你需要使用这些方法;下面描述了这些用例,并针对属性类型有不同的建议(如果不熟悉这些类型的名称,可参考ViewObjects in Detail - View Object Attribute Types and Caching)。

注意:对于Java实体对象,一定不要使用populate*方法来设置主键属性值(这对组合关系可能有不利后果)。应为主键属性使用基本的设置器。对于“刷新插入”行为的PL/SQL实体对象,更多信息,可参考PL/SQLEntity Objects - Creating Primary Keys。

对于所有实体起源的属性类型,不要使用populateAttributeAsChanged(intindex, Object value)方法,除非你真的不关心在提交失败之后能不能重新提交(因为populateAttributeAsChanged()方法的saveOriginal= false)。

实体起源的持久属性

对于视图起源的持久属性,在大多数情况下,你不需要调用populate*方法。为一个新行设置这些属性的默认值,更好的方法是使用基本的设置器方法然后调用OAViewRowImpl.setNewRowState(Row.STATUS_INITIALIZED)方法来把这行作为”临时”的直到用户对其做了修改。更多信息可参考View Object State Management CodingStandard M69。

例外:

1.      要实现“刷新插入”行为的PL/SQL实体对象,你需要调用populateAttribute(index,value, false, false, false)方法。在DML操作之后commit之前,这是必须来立即同步属性值和数据库的值。像上面提到的一样,更多信息,请参考PL/SQLEntity Objects - Creating Primary Keys。

2.      如果你想为实体起源的属性值设置这样它可以和其它用户修改的值一起提交而不触发验证或者不影响实体对象的验证,提交或者事务状态,或者实体对象查询集合的脏标记。比如,OAF框架用这种方式设置标准的WHO字段和ObjectVersionNumber属性值。

实体起源的非持久属性

对于实体起源的非持久属性,通常来说,你应该在实体对象属性的getter(get<AttributeName>())方法计算并返回值而不是设置值。

l  如果因为一些原因,你不能使用这个方法,你仍旧可以使用基本的设置器方法-但是请注意这些调用会更改实体对象的验证,提交和事务状态和视图对象查询集合的脏标记。也要明白你不应该存储任何UI状态到一个实体起源的非持久属性上。

注意:当视图对象行集合在提交后被刷新时,实体起源的非持久属性值会丢失。如果你想保留这些值,请参考Persisting Entity-Derived TransientAttribute Values After Commit 。

l  而不用基本的设置器方法,你可以使用populateAttribute(index,value, false, true, true)(设置markAsChanged属性值为true)来避免触发验证或者影响实体对象验证,提交或者事务状态,或者视图对象查询集合的脏标记。

注意:非持久属性值不映射到任何数据库的表列,因此,不会被提交。也要明白你不应该存储任何UI状态到一个实体起源的非持久属性上。

l  避免使用参数markAsChanged为false的populateAttribute(intindex, Object value) 或者 populateAttribute()方法。