ORA-01653 表空间扩展失败

今天项目的服务器崩了,服务器的风扇不转了,前一阵子只是用服务器的数据库,读写量也小,没发现这个问题。今天更新服务器的Weblogic,估计是
CPU占用量高导致发热后计算错误,磁盘读写错误,先是整个RedHat Read-only file
system,后来直接罢工了,重启出现mount: error 2 ……

———————————————————————
以上是题外话,无奈把数据库备份导入本机XE数据库进行开发,imp时出现错误
IMP-00017: following statement failed with ORACLE error 604:
"DECLARE SREC DBMS_STATS.STATREC; BEGIN SREC.MINVAL := ‘C3020416’; SREC.MAX"
"VAL := ‘C3020416’; SREC.EAVS := 0; SREC.CHVALS := NULL; SREC.NOVALS := DBMS"
"_STATS.NUMARRAY(10321,10321); SREC.BKVALS := DBMS_STATS.NUMARRAY(0,1); SREC"
".EPC := 2; DBMS_STATS.SET_COLUMN_STATS(NULL,’"AFWK_FUNCTIONS"’,’"FUNCTION_I"
"D"’, NULL ,NULL,NULL,1,1,0,srec,5,6); END;"
IMP-00003: ORACLE error 604 encountered
ORA-00604: error occurred at recursive SQL level 1
ORA-01653: unable to extend table SYS.HIST_HEAD$ by 8 in tablespace SYSTEM
ORA-06512: at "SYS.DBMS_STATS", line 4858
ORA-06512: at "SYS.DBMS_STATS", line 5081
ORA-06512: at line 1
看来问题集中在ORA-01653上,貌似SYSTEM的表空间不足导致。

通过如下语句查询表空间
SELECT T.TABLESPACE_NAME,
D.FILE_NAME,
D.AUTOEXTENSIBLE,
D.BYTES,
D.MAXBYTES,
D.STATUS
FROM DBA_TABLESPACES T, DBA_DATA_FILES D
WHERE T.TABLESPACE_NAME = D.TABLESPACE_NAME
ORDER BY TABLESPACE_NAME, FILE_NAME;
发现各表空间的自增均正常,但SYSTEM这一表空间的BYTES = MAXBYTES,已经不能自增了。

修改SYSTEM的表空间最大值
alter database datafile ‘/usr/lib/oracle/xe/oradata/XE/sysaux.dbf’ AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED;

修改后结果如下

问题解决。

ADF Customization part 3: Customization



Part2
介绍了如何启用ADF应用的客制化功能,以允许最终用户在运行时对于应用作出个性化的配置,并将配置结果保存下来,当用户在一次登陆时,展示用户修改过的
界面元素。ADF应用的个性化除了上述功能外,还提供非运行时的客制化功能,即对于已经开发完成的ADF应用进行二次开发,在不修改原始应用的基础上添加
客制化的元素,改变流程等,并将修改后的应用发布。

首先对ADF客制化开发中的一些基本概念进行描述。

Oracle ADF提供了如下几种客制化的模式:

Seeded customization

将客制化应用在整个程序或组,客制化的生命周期为应用部署的周期。Part3的重点描述即在于此。
User customization (改变持久化)

允许个人持久化的客制化应用。如Part2所述。
Design time at runtime

系统分析师或管理员使用,以客制化程序。Oracle Fusion Middleware Developer’s Guide for Oracle WebCenter中有详细介绍。

ADF在客制化应用上引入了客制化层的概念,所有的客制化内容均在客制化层上完成并存储至MDS,而不对已经开发完成的应用作出修改。在运行时将原始应用
与客制化层的内容进行融合,并将最终结果展示给用户。这种方式最大限度的避免了由于应用的客制而导致的混乱,同时保证了对于原始应用的补丁不会影响到客制
化的内容。

允许进行客制化的ADF应用允许设置多个客制化层,例如industry层及site层;而一个客制化层又允许具有多个客制化值,如industry层可以具有healthcare和financial等。但对于运行时的应用来说,每一个层只有一个客制化值有效。

应用实际使用客制化层的顺序由客制化层的优先级来确定。


使用JDeveloper创建客制化类,指定客制化层及客制化层呢个的值,指定客制化层的优先级,即可完成客制化开发。

客制化的类型:Static/Dynamic,Static类型的客制化值将使用客制化定义的初始值,而Dynamic类型的客制化
值则允许在运行时动态改变。customization类可存在于Model或ViewController,若放入Model则必须为Static,因
为每一个应用中Model通常只会初始化一次。ViewController中则可使用Static/Dynamic。通过设置
customization类中getCacheHint()方法返回值可以设置该客制化是Static/Dynamic,例如该方法返回值为
ALL_USERS则客制化为Static。
ALL_USERS – customization为针对某应用全局有效的,通常用于static类型的customization层。
MULTI_USER – 针对复数用户有效的customization。 REQUEST – 针对当前请求有效的customization。
USER – 针对某特定用户有效的customization,通过用户访问应用的Session来决定具体用户。(在Web应用中session通常指代用户访问应用的servlet session)

进行客制化开发:

首先是客制化类的编写。每一个客制化层对应一个客制化类,而客制化类中可定义多个客制化值。

客制化类的编写:

需要包含四个方法如下
CacheHint getCacheHint();

决定customization的类型,返回值包括ALL_USERS, MULTI_USER, REQUEST, USER四种。
String getName();

返回当前customization类对应customization层的名称。
String generateIDPrefix(RestrictedSession sess, MetadataObject mo);

返回在MDS中对当前customization层元素加的前缀,以使该客制化层的元素在MDS中具有唯一标示。这一前缀在所有customization层中必须是唯一的,出于性能考虑应小于4个字符。
String[] getValue(RestrictedSession sess, MetadataObject mo);

返回反映客户化层加载顺序的列表,按照列表正序加载。通常只需要有一个customization层,故该列表通常只返回一个值。

客制化可被用于修改应用以适应某种行业的需求。每一种行业则象征了一个客户化层,并使用一个具体的客户化类予以实现。

使用客制化类实现Seeded Customization :
应用的adf-config.xml中mds-config部分必须配置要使用的客制化类。
客制化类须放置在JDeveloper的classpath下以供访问。(运行时必须存在于可被EAR级别的classLoader访问的路径下) 客制化值必须设置在CustomizationLayerValues.xml文件中。该文件位于JDeveloper安装路径下的jdev文件夹中。该文件中定义的值必须与进行客制化开发的客制化类中的名称相匹配。
(详细配置下半部分有step by step)

满足上述条件后,当JDeveloper以客制化角色启动时,将显示允许定制的客制化层及客制化值,选择需要的客制化层和客制化值后进行客制化即可。

客制化类实例(来自文档B31974)








package mycompany;

import java.io.IOException;

import java.io.InputStream;

import java.util.Properties;

import oracle.mds.core.MetadataObject;

import oracle.mds.core.RestrictedSession;

import oracle.mds.cust.CacheHint;

import oracle.mds.cust.CustomizationClass;

public class IndustryCC extends CustomizationClass {

private static final String DEFAULT_LAYER_NAME = "industry";

private String mLayerName = DEFAULT_LAYER_NAME;

public IndustryCC() {

}

public CacheHint getCacheHint() {

return CacheHint.ALL_USERS;

}

public String getName() {

return mLayerName;

}

public String generateIDPrefix(RestrictedSession sess, MetadataObject mo) {

return new String("I");

}

public String[] getValue(RestrictedSession sess, MetadataObject mo) {

// This needs to return the appropriate value at runtime.

return new String[] { "financial" };

}

}


通常将客制化类单独打包为Jar并以library的方式引入需要进行客制化的应用。在将客制化类打包为Jar时,应同时放置
customization.properties文件以保证客制化类和该文件可以被同一个ClassLoader载入。该配置文件配置了运行时具体每个
客制化层使用的值,内容如下:








#Configured values for the default layer values

industry=financial

site=headquarters



同时,当客制化应用部署时,该客制化类的Jar也应置于应用的ClassPath中以供访问。

创建一个允许进行客制化的应用:

* 启用ViewController的客制化

ViewController的客制化,首先需要保证所有的.jspx和.jsff中的元素具有惟一的id,以供存储入MDS。同时由于使用MDS需要保证源文件基于XML,所以不支持.jsp,需要将.jsp转化为.jspx方可生效。

设置ViewController的属性,启用Seeded Customizations。

  • 启用ResourceBundle的客制化

    点击Application -> Application Properties,在左边选择Resource Bundles,点击Add加入允许进行客制化的ResourceBundle,并勾选Overridden。

  • 修改adf-config.xml

    在Application Navigator中展开Application Resources,修改adf-config.xml。

    在MDS Configuration页中点击add,增加需要使用的客制化类,即之前创建并打包的客制化类。

    注意,当加入多个客制化类(层)时,客制化类(层)将按照自上向下的顺序生效。


对应用进行客制化开发:

在完成客制化类的创建,并启用目标应用的客制化后,即可以Customization Developer Role进入JDeveloper进行目标应用的客制化开发。首先需要配置JDeveloper如下:

  1. 将需要使用的客制化层及客制化值设置入<JDEVELOPER_HOME>/jdev
    /CustomizationLayerValues.xml。当以Customization Developer Role
    进入JDeveloper时,JDeveloper会读取该文件中的客制化层/值的设置,结合当前工程包含的客制化类,决定在JDeveloper的
    Tip Layer中可编辑的客户化层/值。而在应用运行时,则直接从客制化类中读取客制化层/值。本例中在该文件中加入如下值:








    <cust-layers xmlns="http://xmlns.oracle.com/mds/dt"&gt;

    <cust-layer name="industry" id-prefix="i">

    <cust-layer-value value="financial" display-name="Financial" id-prefix="f"/>

    <cust-layer-value value="healthcare" display-name="Healthcare" id-prefix="h"/>

    </cust-layer>

    <cust-layer name="site" id-prefix="s">

    <cust-layer-value value="headquarters" display-name="HQ" id-prefix="hq"/>

    <cust-layer-value value="remoteoffices" display-name="Remote" id-prefix="rm"/>

    </cust-layer>

    </cust-layers>


  2. 确保客制化类打包的Jar位于JDeveloper的Classpath下,切入Customization Developer
    Role时JDeveloper将根据CustomizationLayerValues.xml中配置的值读取该客制化类。通常可将其放置
    在<JDEVELOPER_HOME>/jdev/lib/patches/ 目录下。

  3. 在JDeveloper中选择 Tools -> Preferences -> Roles,选择Customization Develoepr并确定后重新启动JDeveloper。
    如果如上配置正确,且打开对应的可客制化的工程,则应该在Tip Layer中看到如下内容
    (这
    里虽然我的CustomizationLayerValues.xml中配置了industry及site两个层,但因为
    CustomizationDemo这个项目包含的客制化Jar只含有industry一个客制化类,所以这里能够配置的Tip
    Layer中只有industry一个)
    配置成功后即可在Customization Developer Role 下进行客制化开发,在Tip
    Layer中选择需要使用的客制化层及客制化值,之后按照原有ADF应用开发方式进行开发即可。区别在于对于应用的更改只作用于选择的层次/值生效的时
    刻,且所有的更改均不会影响到原应用,而是存储在项目路径下mdssys/cust/<客制化层名称>/<客制化值名称>/下,
    以XML形式存储。在应用部署时,这里的XML数据将被部署至服务器MDS内。可以通过上图所示 "View without
    Customization" 及 "Edit with following Customization Context"
    随时在原始应用/客户化开发应用间进行切换。

客制化应用实例:
以Oracle 数据库自带HR
Schema下EMPLOYEES表为例,创建含有Form的页面用于更新该表,并在EO的Salary字段添加Range类型验证为
2000-25000。后在Customization Developer Role下将范围改为2000-30000,运行测试。

以下为示例链接,注意CustomizationDemo应用需要修改引入的客制化jar包路径,该包位于CustomizationClassDemo应用deploy路径下。
Demo下载


ADF Customization part 2: Personalization

ADF应用的客制化包含两个方面,一方面是允许在运行时,由最终用户对应用进行客制化,如针对用户调整表格的显示状态、查询面板的默认查询、
PanelBox的展开状态等,即Personialization;另一方面是允许针对已开发完成的应用进行定制,如修改页面模板、修改页面字段显示
值、修改页面跳转逻辑等,即Customization。这些客制化内容均不会对已开发完成的应用作出修改,而是存储在MDS中。本文主要介绍如何为
ADF应用启用Personialization。

JDeveloper Ver. 11.1.1.2.0
DB Ver. 10g(XE), Schema HR

启用Personialization步骤:

1. 使用默认角色进入JDeveloper

2. 设
置应用中ViewController项目的属性,在"ADF View"下勾选"Enable User
Customizations","Enable Seeded Customizations",并选择"Across Session using
MDS"以使客户化可以保存下来。

3. 在 Appliaction Navigator 的 Application Resources 中,修改adf-config.xml
在 MDS Configuration 中增加 Customization Classes UserCC,包路径为oracle.adf.share.config.UserCC,以允许针对用户的客制化。
在 View 中,确认 Tag Library URI 为 http://xmlns.oracle.com/adf/faces/rich,这里是用于配置哪一组标签及其属性将被存储至MDS,这里声明为ADF Rich Components。
而 Tags 中则可新增允许进行客制化的标签类型及属性。这里增加几种常用标签

4. 设定页面元素是否允许客制化修改

应用完成上述3步骤的配置后,将为整个应用中adf-config.xml中指定的类型控件及属性启用客户化支持。但在实际使用中往往会遇到应用中不同页
面同种控件部分需要客制化,部分不允许客制化的情况。则需对页面控件设置 persist 及 dontpersist 属性。
需要注意的两点:

persist 及 dontpersist 属性只对于将客制化信息存入MDS的情况有效。 在任何情况下如果客制化信息保存至MDS失败,则仅将客制化信息保存在当前Session中。
控件默认将所有客制化信息保存至MDS,可以点击persist/dontpersist的edit进行可用属性的编辑。 dontpersist的优先级高于persist,即当同一属性被设置入persist及dontpersist,则该属性的客制化信息不会保存入MDS。至此完成应用的客制化定义部分。

由于本示例为针对用户的客制化定义,因此接下来需要定义应用的安全验证及用户,至少定义两个用户用于验证客制化的定义。

1. 进
入 "Configure ADF Security" (Application -> Secure -> Configure
ADF Security),在Step1中选择 "ADF Authentication and Authorization"。

2. Step2,确认需要应用验证的Web项目,选择HTTP Basic Authentication。这里HTTP Basic Authentication即为最常用的Web验证方式,使用浏览器的弹出窗口进行验证。

3. Step3,确认选择为 "No Automatic Grants",点击下一步

4. Step4,确认没有勾选 "Redirect Upon Successful Authentication" ,并点击Finish完成定义。

5. 进行jazn-data.xml的配置,Application -> Secure -> Application Roles,增加Role,此示例使用DjTestRole

6. 点击Users,增加两个用户名为user1,user2,密码分别为password1,password2。

7. 点击Application Roles,为第五步创建的组增加成员user1及user2

8. 点击左下角ADF Policies,将需要访问的页面/taskflow授权给之前创建的Role,并确认勾选Customize, Grant, Personalize



此完成应用的配置,运行应用,分别以user1/user2登录,对于表格列的操作,则对于已经定义允许客户化的控件的状态修改将依用户区分保存至
MDS。如使用user1登录后修改表格显示的列及列宽,则user1下一次登录将看到本次的修改结果;而user2看到的表格显示状态不随user1的
修改而改变。

附注:
对于启用基于MDS的客制化支持后QueryPanel不能保存自定义查询,报出异常
oracle.mds.exception.ReadOnlyStoreException:
MDS-01273: 未能对资源 /persdef/dj/demo/model/queries/EmployeesVO.xml 执行操作,
因为映射到名称空间 / BASE DEFAULT 的源元数据存储为只读。

的问题,Oracle官方在JDeveloper 11.1.1.1.0 的 Release Note 中有提到,需要在应用的adf-config.xml中<mds-config>节点下<cust-config>节点后配置如下内容
<mds-config>
……
<cust-config>
……
</cust-config>
<persistence-config>
<metadata-namespaces>
<namespace path="/persdef" metadata-store-usage="MAR_TargetRepos"/>
</metadata-namespaces>
<metadata-store-usages>
<metadata-store-usage id="MAR_TargetRepos" deploy-target="true"

default-cust-store="true"></metadata-store-usage>

</metadata-store-usages>



</persistence-config>
……
</mds-config>
则关于查询面板的客制化信息将存储在MDS目录下的/persdef目录中。详见ADF Customization part 1: The MDS
经实际部署发现,11.1.1.2.0版本中,服务器MDS分区名称必须为persdef,否则查询面板的个性化保存会报错。应该是Oracle开发人员尚未完善该功能。关于应用的部署,见ADF Customization part 4: Deploy.

Demo下载

ADF How To Use Checkbox in RichTable



JDeveloper 11.1.1.2.0
Oracle 10g EE

在开发中经常遇到的一种情况是需要将Table中某列的两种状态,如Y/N在界面上表现为checkbox的形式。ADF中checkbox默认返回true/false,不符合数据表中存储数据的要求。故需要对true/false进行转换。这里有两种方式完成转换。



1. 在ViewController端页面的PageDef.xml文件中添加对应字段的绑定
类型为Button,选择对应的AM,VO,字段名称,如果该字段具有LOV,不需要选择对应LOV而保留None即可。在Selected State Value中填写勾选时需要的值,Unselected State Value中选择飞勾选状态时的值
后将界面控件通过el表达式关联至该绑定即可。通常将属性由Application Navigator中拖动入界面时会自动完成该绑定添加的过程。

2. 遵
循MVC的原则,修改VO对应字段的get/set方法,将ViewController返回的true/false转换为需要的字符。具体做法为在对应
VO属性中的Java页生成Java文件,只需勾选Generate View Row Class并勾选Include
accessors,后再修改生成的Java文件中对应字段的get/set方法即可。


况在RichTable等Collection Component中有所不同。不同于界面上其他控件的属性绑定方式,ADF
RichTable等Collection
Component通常绑定文件中为tree类型,而控件则使用el表达式访问该tree的collectionModel或treeModel
而Richtable中的列则通过row.bindings.XXX.inputValue的方式来访问该tree中的每一行值
而在页面的PageDef.xml文件中添加tree类型的绑定时,只可以选择绑定到的VO列名称,而没有属性可以设置将该列的值映射为checkbox的true/false。

ADF中使用将tree类型绑定中的树形绑定入另一button类型绑定,并在该button类型绑定中设置Selected/Unselected值的方式完成值的转换。具体内容如下:


1. 在PageDef.xml中添加tree类型并包含目标字段,添加button类型的绑定,映射至VO对应字段。

2. 设置button类型绑定的Selected/Unselected等属性
3. 点击编辑器左下角进入Source模式,找到tree类型绑定的代码,形如
<tree IterBinding="XXXXX" id="XXXXX">
<nodeDefinition DefName="XXXXX" Name="XXXXX">
<AttrNames>
<Item Value="XXXXX"/>
<Item Value="XXXXX"/>
<Item Value="XXXXX"/>
</AttrNames>
</nodeDefinition>
</tree>
修改需要使用Checkbox的字段,将其绑定至第一步创建的button类型绑定
<tree IterBinding="XXXXX" id="XXXXX">
<nodeDefinition DefName="XXXXX" Name="XXXXX">
<AttrNames>
<Item Value="XXXXX"/>
<Item Value="XXXXX"/>
<Item Value="EnabledFlag" Binds="EnabledFlag"/>
</AttrNames>
</nodeDefinition>
</tree>


此便完成了RichTable等CollectionComponent中checkbox的设置。需要注意的是通常这些设置在开发者将
Application
Navigator中的属性拖入界面RichTable中并选择展现为CheckBox时会自动完成,但在某些特定情况下,如该VO中目标属性具有LOV
时,由于IDE本身的BUG(?)导致上述Binds="XXX"及button类型的绑定没有自动生成,则需要手工修正绑定以达到所需效果。

ADF Faces, rollback bug

JDeveloper Ver. 11.1.1.2.0
DB Ver. Oracle 10g EE

BUG发生条件
1. 页面为jsff
2. 页面使用RichTable,绑定某VO,且该VO中某列具有LOV,该LOV以Choice List(下拉列表)的形式展现
3. 页面有Command Button/Link绑定VO的CreateInsert方法,且其Disabled属性绑定为#{!bindings.CreateInsert.enabled}
4. 页面有Command Button/Link绑定VO所在AM的Rollback方法

BUG现象
在页面点击Rollback,发现RichTable中下拉列表内的值消失,且无可选择项。刷新后可选项重新出现。

BUG原因

CreateInsert button的Disabled属性绑定。将其置为Default即可解决。

程序示例,使用Oracle示例HR数据库中Employees表。

ADF 查询面板 关联LOV



ADF查询面板提供了快速创建查询的功能,本文主题为在ADF查询面板中使用关联LOV,即B LOV的结果依赖于A LOV的选择值,A LOV选择值变动时自动清空B LOV中的值。

示例使用Oracle HR数据库中的Employees, Locations, Departments三张数据表,Departments外键关联至Locations数据表,Employees数据表外键关联于Locations数据表。

使用2009年11月11日发布的Oracle JDeveloper 11.1.1.2.0作为开发环境,经实践其前一版本11.1.1.1.0在查询面板选择时清空LOV存在BUG。

首先从数据库反向创建相关EO、VO
修改DepartmentsView,在Query标签页为其创建Bind Variable,名称为locationId,类型为String。注意将其属性中的Display Hints设为Hide

并修改相应SQL语句,添加where条件如下
WHERE Departments.LOCATION_ID=nvl(:locationId, Departments.LOCATION_ID)

修改EmployeesView,在Query标签页修改SQL语句如下
SELECT Employees.EMPLOYEE_ID,
Employees.FIRST_NAME,
Employees.LAST_NAME,
Employees.EMAIL,
Employees.PHONE_NUMBER,
Employees.HIRE_DATE,
Employees.JOB_ID,
Employees.SALARY,
Employees.COMMISSION_PCT,
Employees.MANAGER_ID,
Employees.DEPARTMENT_ID,
Locations.LOCATION_ID
FROM EMPLOYEES Employees,
DEPARTMENTS Departments,
LOCATIONS Locations
WHERE Employees.DEPARTMENT_ID = Departments.DEPARTMENT_ID
AND Departments.LOCATION_ID = Locations.LOCATION_ID

在ViewAccessors页面添加ViewAccessor,分别指向DepartmentsView及LocationsView。

修改DepartmentsView1,将其绑定变量的Value设定为LocationId(这里的LocationId即为上一步修改SQL后EmployeesView中新添加的Attribute名称)。

在Attributes标签页为DepartmentId及LocationId分别添加LOV。

DepartmentId添加LOV,设定DataSource为上一步创建的ViewAccessor
DepartmentsView1,Attribute为DepartmentId,并添加返回值为DepartmentId,修改UI
Hints标签页中的Default List Type为Input Text With List of Values


同样为LocationId添加LOV,设定DataSource为上一步创建的ViewAccessor LocationsView1,Attribute为LocationId,并添加返回值为LocationId,修改UI
Hints标签页中的Default List Type为Input Text With List of Values。

在Attribute标签页为DepartmentId设置属性,在其Dependencise中选择LocationId


最后,创建页面,将Data Controls中EmployeesView的All Queriable Attributes拖入界面,选择Query -> ADF Query Panel with Table。执行测试。

ADF根据行状态调整页面元素显示

JDeveloper 11.1.1.2.0

Oracle 10g (hr schema)

某应用开发中碰到需要根据行状态决定页面元素的显示状态的要求。具体要求如下:

存在页面page1与page2,数据表table1与table2,table1与table2为Master-Detail关系,使用taskflow控制页面跳转。

page1选择新建按钮跳转到page2,此时page2页面指定按钮refresh按钮不允许点击。当用户在page2完成对table1的创建/修改
操作并保存后,页面refresh按钮允许点击;当用户从page1通过修改按钮跳转至page2后,若不对table1的记录进行修改,则
refresh按钮允许点击,否则refresh按钮不允许点击。

按照通常做法,需配置taskflow级别变量用于记录table1中某行状态,在页面跳转及记录值变动时修改该行状态,并根据该行状态变量决定refresh按钮的可用性。这种做法的缺点在于需要定义变量,并在多处操作时对该变量值进行维护。

故直接取EntityObject行状态作为标志位进行判断。下例以hr schema中regions及countries作为示例。

分别创建View页面和Update页面,View页面放置regions表,并允许进行新增和修改的操作。

若通过新增按钮跳转至Update页面,或通过修改跳转至Update页面并对region信息作出修改,则refresh按钮不允许点击,否则refresh按钮允许点击,通过判断当前regions EntityObject的状态完成。

EntityObject在生命周期中具有五种状态

STATUS_UNMODIFIED - Entity Object源于数据库,且没有被修改过,或者修改已经被提交至数据库。 STATUS_MODIFIED - Entity Object源于数据库,当前已经被修改且在当前事务中修改没有提交至数据库。
STATUS_NEW - Entity Object为当前事务中新建的。 STATUS_DELETED - Entity Object在当前事务中被删除。

STATUS_DEAD - Entity Object为当前事务中新建的,且没有提交至数据库即被删除。

而各状态对应static值现下表




























oracle.jbo.server.Entity

public static final byte


STATUS_DEAD
4


public static final byte


STATUS_DELETED
3


public static final byte


STATUS_MODIFIED
2

public static final byte
STATUS_UNMODIFIED
1

*oracle.jbo.Row



public static final byte

STATUS_NEW

0





故只需修改Update页面的refresh按钮Disabled属性,通过EL表达式进行行状态判断,进而返回true/false即可。

ADF
中ViewController通过EL表达式绑定取得Model中属性的值,当前IDE只提供了很少数的语法提示,那么根据Java命名规则,在
Model层通过getAbc()取得的值,在ViewController中该Abc作为对象abc存在,则可通过EL表达式#
{bindings.XXX.abc}取得Model层XXX.getAbc()取得的值。

故通过查阅Fusion Middleware API,可知EL表达式应写作

#{bindings.RegionsView1Iterator.currentRow.entities[‘0’].entityState == ‘1’ ? false : true}

示例下载

ADF Customization part 1: The MDS

Oracle Fusion Middleware中的客户化(Customization)均通过Oracle Metadata
Services(MDS)加以实现,客户化开发允许开发人员、用户或系统分析人员在运行时灵活的对程序进行修改。本文主要介绍MDS在ADF客户化应用时的作用、配置。ADF中实现客户化的几种方式将稍后介绍。

示例环境:
Oracle JDeveloper 11.1.1.2.0
Oracle XE (HR schema)

Oracle Metadata Services用于存储用户在对Fusion Application进行客户化开发/个性化时所作的修改。这里包括两方面内容:

1. 利用JDeveloper针对已经开发完成的Fusion Application进行客户化开发,设置客户化层,以使同一应用针对不同的使用环境(如医疗行业/金融行业,A公司/B公司)具有不同的展现形式等,而又不破坏原有的应用。
2. 终端用户或具有权限的系统管理员登录进入运行中的Fusion Application,通过拖拽、点击等方式对可定制的界面元素进行设置,如设置表格列宽、设置表格列显示顺序、设置默认搜索条件、设置控件的展开/收缩状态等,并将修改应用至指定用户/组中。所
有的这些修改,均将保存入Oracle Metadata Services
repository中,并允许在发布应用时将MDS中内容打包入MAR(Metadata
Archive),再将存储客户化信息的MAR打包入EAR进行Fusion Application的发布。

MDS repository支持两种方式的实现:文件/数据库。使用JDeveloper新建的ADF应用默认使用基于文件的MDS repository,并允许通过配置Profile的方式调整repository至数据库。

本文以下将介绍基于文件的MDS repository,基于数据库的MDS repository请至此观看(源地址已经被平平安安W.A.L.L掉了,此地址为转载 + 翻译)。

ADF应用默认使用基于文件的MDS repository,通过Application -> Application Properties,展开RUN节点,即可看到当前应用的MDS配置

可以看到应用使用默认MAR Profile,当前MDS repository的存储位置,以及是否在每次执行应用前清空MDS存储客户化信息。

对于已经进行客户化的应用,打开默认MDS repository路径
路径中queryTest为启用客户化的应用的名称,而mdssys即为系统默认MDS repository的存储文件夹。persdef为我的客户化应用中定义的自定义查询存储的repository。

展开mdssys可看到如下结构

以看到在queryTest这个应用中,包括user1、user2这两个用户的客户化信息,该信息来自于运行时分别以这两个用户的身份进行登录,并针对
queryTest.jspx中的一个表格(AdfRichTable)中的列进行客户化(增、删显示的列,调整列的顺序及列宽等),则客户化结果被保存
至MDS repository中以页面名称命名的XML文件中。

打开user1/queryTest.jspx.xml,看到对于表格列的客制化信息:
<?xml version = ‘1.0’ encoding = ‘UTF-8’?>
<mds:customization version="11.1.1.55.36" xmlns:mds="http://xmlns.oracle.com/mds"&gt;
<mds:modify element="resId1c1">
<mds:attribute name="visible" value="true"/>
<mds:attribute name="width" value="126"/>
</mds:modify>
<mds:modify element="resId1c2">
<mds:attribute name="visible" value="true"/>
</mds:modify>
<mds:modify element="resId1c4">
<mds:attribute name="visible" value="true"/>
</mds:modify>
</mds:customization>
从上述文件可看出改客制化信息定义了分别定义了queryTest.jspx页面中ID为resId1c1, resId1c2, resId1c4的控件的可见性、宽度等信息。

ADF 查询面板 关联LOV

ADF查询面板提供了快速创建查询的功能,本文主题为在ADF查询面板中使用关联LOV,即B LOV的结果依赖于A LOV的选择值,A LOV选择值变动时自动清空B LOV中的值。

示例使用Oracle HR数据库中的Employees, Locations, Departments三张数据表,Departments外键关联至Locations数据表,Employees数据表外键关联于Locations数据表。

使用2009年11月11日发布的Oracle JDeveloper 11.1.1.2.0作为开发环境,经实践其前一版本11.1.1.1.0在查询面板选择时清空LOV存在BUG。

首先从数据库反向创建相关EO、VO
修改DepartmentsView,在Query标签页为其创建Bind Variable,名称为locationId,类型为String。注意将其属性中的Display Hints设为Hide

并修改相应SQL语句,添加where条件如下
WHERE Departments.LOCATION_ID=nvl(:locationId, Departments.LOCATION_ID)

修改EmployeesView,在Query标签页修改SQL语句如下
SELECT Employees.EMPLOYEE_ID,
Employees.FIRST_NAME,
Employees.LAST_NAME,
Employees.EMAIL,
Employees.PHONE_NUMBER,
Employees.HIRE_DATE,
Employees.JOB_ID,
Employees.SALARY,
Employees.COMMISSION_PCT,
Employees.MANAGER_ID,
Employees.DEPARTMENT_ID,
Locations.LOCATION_ID
FROM EMPLOYEES Employees,
DEPARTMENTS Departments,
LOCATIONS Locations
WHERE Employees.DEPARTMENT_ID = Departments.DEPARTMENT_ID
AND Departments.LOCATION_ID = Locations.LOCATION_ID

在ViewAccessors页面添加ViewAccessor,分别指向DepartmentsView及LocationsView。

修改DepartmentsView1,将其绑定变量的Value设定为LocationId(这里的LocationId即为上一步修改SQL后EmployeesView中新添加的Attribute名称)。

在Attributes标签页为DepartmentId及LocationId分别添加LOV。

DepartmentId添加LOV,设定DataSource为上一步创建的ViewAccessor
DepartmentsView1,Attribute为DepartmentId,并添加返回值为DepartmentId,修改UI
Hints标签页中的Default List Type为Input Text With List of Values


同样为LocationId添加LOV,设定DataSource为上一步创建的ViewAccessor LocationsView1,Attribute为LocationId,并添加返回值为LocationId,修改UI
Hints标签页中的Default List Type为Input Text With List of Values。

在Attribute标签页为DepartmentId设置属性,在其Dependencise中选择LocationId

最后,创建页面,将Data Controls中EmployeesView的All Queriable Attributes拖入界面,选择Query -> ADF Query Panel with Table。执行测试。

Oracle LOB 字段导入

测试环境1:AIX + Oracle 9i
测试环境2:RedHat + Oracle 10g
正式环境:AIX + Oracle 9i

近做了一个关于jBPM4.0的工作流项目,项目完成后需要向正式环境迁移和备份。发现使用exp命令导入的dmp文件在向另外的测试环境和正式环境导入
时,所有带有数据库大对象字段的数据表(BLOB,CLOB)均无法正常导入,甚至在目标schema下连数据表都没有创建。

通常在向目标schema imp具有LOB字段的表时可能遇到两种错误:

1. 目标schema扩展空间不足,这个可能是在创建schema时进行了限制,解决方法是扩大即可。
2. 目
标数据库没有原始数据库放置LOB字段表的表空间。imp在导入含有LOB字段的表时,dmp从原始数据库哪个表空间导出的,那么含有LOB字段的表就会
在目标数据库尝试在相应表空间中创建表并执行导入。若目标数据库没有相应表空间则会报错,导致导入失败。而imp在导入其他不含有LOB字段的表时,会将
表导入到当前user的default tablespace中。
针对问题2,有两种解决方法

1. 在目标schema下创建好含有LOB字段的表,并针对这些表进行导入(imp tables=(table1,table2))
2. 在目标数据库创建与原数据库相同名称的表空间并授权给目标user,将目标用户在default tablespace中的配额设置为0。
附:设置当前用户TableSpace的方法,假设原default tablespace为USERS,目标表空间为TARGET,目标schema为GEEKERDEVER,且已经将TARGET授权给GEEKERDEVER
grant dba to GEEKERDEVER; //赋DBA权限
revoke unlimited tablespace from GEEKERDEVER; //撤销此权限
alter user GEEKERDEVER quota 0 on USERS; //将用户在USERS表空间的配额置为0
alter user GEEKERDEVER quota unlimited on TARGET; //设置在用户在myhuang表空间配额不受限。