Jdev版本:11.1.1.7
我使用以下查询创建了一个基于部门VO的部门EO:
SELECT DeptEO.DEPARTMENT_ID,
DeptEO.DEPARTMENT_NAME,
DeptEO.MANAGER_ID,
DeptEO.LOCATION_ID,
DeptEO.ACTIVE
FROM DEPARTMENTS DeptEO where DeptEO.DEPARTMENT_ID > 250
UNION
SELECT 280 , 'Advertising',200,1700,'Y' from Dual
为简单起见,我使用了双表中的示例语句,在实际场景中,UNION子句之后的查询将从表中填充。 运行查询后,我会在UI上获得所需的结果。
现在我的要求是将DEPARTMENT_ID为280的新创建的行插入到DB表DEPARTMENTS中。 提交时,ADF抛出错误为“oracle.jbo.RowAlreadyDeletedException:JBO-29114”这是正确的,因为DB表中缺少此行,所以当它在行上进行锁定以进行更新时,它找不到什么。
有没有办法可以指示ADF将此行视为Insert而不是更新。 我们还尝试将此行的数据填充到从RowSetIterator创建的新行实例中,然后通过调用removeFromCollection()然后插入重复的行来删除罪魁祸首行,但仍然没有运气。
我们正在考虑的其他方法是:
1-创建另一个VO / EO并通过它们在表中插入值。 2-为此查询创建数据库视图并在此视图上触发,因此当更新操作到来时,我们会在触发器中执行逻辑,即决定是更新还是插入数据。
请您指导在这种情况下应该做些什么。
此致
亚洲时报Siddharth
编辑:插入行的代码(我正在尝试但它不起作用)
RowSetIterator rsi=iterator.getRowSetIterator();
Row editableRow= rsi.createRow();
while(rsi.hasNext()){
Row r =rsi.next();
if((""+r.getAttribute("DepartmentId")).toString().equals("280") ){
System.err.println("? Equality row found!!!");
editableRow.setAttribute("DepartmentId", r.getAttribute("DepartmentId"));
editableRow.setAttribute("DepartmentName", r.getAttribute("DepartmentName"));
editableRow.setAttribute("ManagerId", r.getAttribute("ManagerId"));
editableRow.setAttribute("LocationId", r.getAttribute("LocationId"));
editableRow.setAttribute("Active", r.getAttribute("Active"));
rsi.removeCurrentRowFromCollection();
}
}
if(editableRow !=null){
System.err.println("? Row value after removal : "+editableRow.getAttribute("DepartmentName"));
rsi.insertRow(editableRow);
operBindingCommit.execute();
}
答案 0 :(得分:1)
您的用例可以通过几种方式实现。第一种方法是迭代托管bean中的行集,并检查id为280的部门是否存在,如果是,则更新该行,否则使用department VO的参数调用Create。第二种方式,也就是更好的方法,是在业务组件级别创建一个更新/插入方法,在ViewObjectImpl或ApplicationModuleImpl中,然后从托管bean调用它。
以下是用VOImpl
编写的插入/更新方法的示例代码public void updateInsertJobs(String jobId, String jobTitle,
String minSalary, String maxSalary)
{
RowSetIterator rSet = this.createRowSetIterator(null);
JobsViewRowImpl row = new JobsViewRowImpl();
Boolean jobExist = false;
if (null != jobId)
{
try
{
while (rSet.hasNext())
{
row = (JobsViewRowImpl) rSet.next();
if (row.getJobId().equals(jobId))
{
row.setJobTitle(jobTitle);
row.setMinSalary(new Number(minSalary));
row.setMaxSalary(new Number(maxSalary));
jobExist = true;
}
}
if (!jobExist)
{
JobsViewRowImpl r = (JobsViewRowImpl) this.createRow();
r.setJobId(jobId);
r.setJobTitle(jobTitle);
r.setMinSalary(new Number(minSalary));
r.setMaxSalary(new Number(maxSalary));
this.insertRow(r);
}
this.getDBTransaction().commit();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
确保在Client Interface中公开该方法,以便能够从数据控件中访问它。
以下是如何从托管bean调用该方法:
public void insertUpdateData(ActionEvent actionEvent)
{
BindingContainer bc =
BindingContext.getCurrent().getCurrentBindingsEntry();
OperationBinding oB = bc.getOperationBinding("updateInsertJobs");
oB.getParamsMap().put("jobId", "TI_STF");
oB.getParamsMap().put("jobTitle", "Technical Staff");
oB.getParamsMap().put("minSalary", "5000");
oB.getParamsMap().put("maxSalary", "18000");
oB.execute();
}
一些可能有用的参考资料:
答案 1 :(得分:0)
由于自定义sql查询,您的视图对象变为只读 但是,您仍然可以使用实体在dept表中创建行。
创建包含DeptEO
访问器的java实现。
在视图对象中创建自定义方法并创建新实体或使用实体定义更新现有实体。要查找所需的行,您可以检查具有此键的实体是否已存在。这样的事情(假设deptId是你的主键):
public void createOrUpdateDept(BigInteger deptId){
DeptEOImpl dept;
EntityDefImpl deptDef = DeptEOImpl.getDefinitionObject();
Key key = new Key(new Object[]{deptId});
dept = deptDef.findByPrimaryKey(getDBTransaction(), key);
if (dept == null){
// Creating new entity if it doesn't exist
dept = deptDef.createInstance2(getDBTransaction(), null);
dept.setDepartmentId(deptId);
}
// Changing other attributes
dept.setDepartmentName("New name");
// Commiting changes and refreshing ViewObject if required
getDBTransaction().commit();
executeQuery();
}
此代码只是一个示例,使用它作为参考/想法,不要盲目复制/粘贴。