0

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 的行插入到数据库表 DEPARTMENTS 中。提交时,ADF 将错误抛出为“oracle.jbo.RowAlreadyDeletedException: JBO-29114”,这是正确的,因为 DB 表中缺少该行,因此当它锁定该行以进行更新时,它没有找到任何事物 。

有什么方法可以指示 ADF 将此行视为 Insert 而不是 update 。我们还尝试将此行的数据填充到从 RowSetIterator 创建的新行实例中,然后通过调用 removeFromCollection() 删除罪魁祸首行,然后插入重复的行,但仍然没有运气。

我们正在考虑的其他方法是:

1- 创建另一个 VO/EO 并通过它们在表中插入值。2-为此查询创建一个数据库视图并在此视图上触发,所以当更新操作到来时,我们在触发器中执行我们的逻辑,即决定是更新还是插入数据。

您能否指导在这种情况下应该做什么。

问候,

悉达多

编辑:插入行的代码(我正在尝试但它不起作用)

    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();
    }
4

2 回答 2

1

您的用例可以通过多种方式实现。第一种方法是遍历托管 bean 中的行集并检查是否存在 id 为 280 的部门,如果存在则更新该行,否则使用部门 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();
      }
    }
}

确保在客户端接口中公开该方法,以便能够从数据控制中访问它。

以下是如何从托管 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();
}

一些可能有帮助的参考资料:

于 2015-01-24T00:07:52.560 回答
0

由于自定义 sql 查询,您的视图对象变为只读。
但是,您仍然可以使用实体在 dept 表中创建行。

创建 java 实现,包括DeptEO.
在视图对象中创建自定义方法并创建新实体或使用那里的实体定义更新现有实体。要查找所需的行是否存在,您可以检查具有此键的实体是否已存在。像这样的东西(假设 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();
  }

这段代码只是一个示例,作为参考/想法,不要盲目复制/粘贴。

于 2015-01-28T09:48:05.787 回答