Вставка / обновление строк в таблицу БД, где строки получаются из VO [Backed by EO] на основе Union Query

Jdev Версия: 11.1.1.7

Я создал отдел EO на основе отдела VO со следующим запросом:

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 будет заполняться из таблицы. После выполнения запроса я получаю желаемый результат в пользовательском интерфейсе.

Теперь мое требование состоит в том, чтобы вставить эту вновь созданную строку с DEPARTMENT_ID, равным 280, в таблицу DB DEPARTMENTS. При фиксации ADF выдает ошибку как " oracle.jbo.RowAlreadyDeletedException: JBO-29114 ", которая является правильной, так как эта строка отсутствует в таблице БД, поэтому, когда она идет для получения блокировки строки для обновления, она не находит что-нибудь.

Есть ли способ, которым я могу поручить ADF рассмотреть эту строку для вставки, а не обновления. Мы также попытались заполнить данные этой строки новым экземпляром строки, созданным из 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();
    }

2 ответа

Ваш вариант использования может быть реализован несколькими способами. Первый способ - выполнить итерацию по набору строк в управляемом компоненте и проверить, существует ли отдел с идентификатором 280, если да, то обновить строку, в противном случае вызвать Create с параметрами для VO отдела. Второй способ, и он сказал бы, что лучше, - это создать метод для обновления / вставки на уровне бизнес-компонента, либо в ViewObjectImpl, либо в ApplicationModuleImpl, а затем вызвать его из управляемого компонента.

Вот пример кода для метода вставки / обновления, написанный на 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();
      }
    }
}

Убедитесь, что метод открыт в клиентском интерфейсе, чтобы иметь доступ к нему из управления данными.

Вот как вызвать метод из управляемого компонента:

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

Некоторые ссылки, которые могут быть полезны:

Ваш объект просмотра становится доступным только для чтения из-за пользовательского запроса 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();
  }

Этот код является просто примером, используйте его как ссылку / идею, не копируйте и не вставляйте слепо.

Другие вопросы по тегам