Обновите строку, если ссылки существуют, в противном случае удалите с помощью весенней загрузки - PullRequest
0 голосов
/ 23 октября 2019

Требуется руководство -

Как выполнить полное удаление, если ссылка отсутствует, и выполнить мягкое удаление, если ссылка доступна, эту операцию следует выполнять одним методом.

Например, I1 главная таблица и 3 транзакционные таблицы, а главная ссылка доступна во всех 3 транзакционных таблицах. Теперь, удаляя главную строку, я должен сделать следующее: Если основная ссылка доступна, обновите строку основной таблицы и, если нет основной ссылки. доступно удалить строку.

Я пытался следовать до сих пор.

Реализация службы -

public response doHardOrSoftDelete(Employee emp) {
    boolean flag = iMasterDao.isDataExist(emp);
    if(flag) {
        boolean result = iMasterDao.doSoftDelete(emp);
    } else {
        boolean result = iMasterDao.doHardDelete(emp);
    }
}

Второй подход:

Как известно, при удалении записи, если ссылкадоступно, затем выдает ConstraintViolationException , поэтому мы можем просто перехватить его и проверить, что перехваченное исключение относится к типу ConstraintViolationException или нет, если да, тогда вызовите метод doSoftDelete () и верните ответ. Так что здесь вам не нужно писать метод или что-либо еще, чтобы проверить ссылки. Но я не уверен, правильный ли это подход или нет. Просто помогите мне с этим.

Вот что я попробовал еще раз -

public Response deleteEmployee(Employee emp) {
    Response response = null;
    try{
    String status= iMasterDao.deleteEmployeeDetails(emp);
    if(status.equals("SUCCESS")) {
        response = new Response();
        response.setStatus("Success");
        response.setStatusCode("200");
        response.setResult("True");
        response.setReason("Record deleted successfully");
        return response;    
    }else {
        response = new Response();
        response.setStatus("Fail");
        response.setStatusCode("200");
        response.setResult("False");
    }
    }catch(Exception e){
        response = new Response();
         Throwable t  =e.getCause();
         while ((t != null) && !(t instanceof ConstraintViolationException)) {
            t = t.getCause();
         }
         if(t instanceof ConstraintViolationException){
            boolean flag = iMasterDao.setEmployeeIsDeactive(emp);
            if(flag) {
                 response.setStatus("Success");
                 response.setStatusCode("200");
                 response.setResult("True");
                 response.setReason("Record deleted successfully");
            }else{
                response.setStatus("Fail");
                response.setStatusCode("200");
                response.setResult("False");
            }
         }else {
             response.setStatus("Fail");
             response.setStatusCode("500");
             response.setResult("False");
             response.setReason("# EXCEPTION : " + e.getMessage()); 
         }
    }
    return response;
}

Реализация Дао -

public boolean isDataExist(Employee emp) {
    boolean flag = false;       
    List<Object[]> tbl1 = session.createQuery("FROM Table1 where emp_id=:id")
    .setParameter("id",emp.getId())
    .getResultList();

    if(!tbl1.isEmpty() && tbl1.size() > 0) {
        flag = true;
    }

    List<Object[]> tbl2 = session.createQuery("FROM Table2 where emp_id=:id")
    .setParameter("id",emp.getId())
    .getResultList();

    if(!tbl2.isEmpty() && tbl2.size() > 0) {
        flag = true;
    }

    List<Object[]> tbl3 = session.createQuery("FROM Table3 where emp_id=:id")
    .setParameter("id",emp.getId())
    .getResultList();

    if(!tbl3.isEmpty() && tbl3.size() > 0) {
        flag = true;
    }

    return flag;
}

public boolean doSoftDelete(Employee emp) {
    empDet = session.get(Employee.class, emp.getId());
    empDet .setIsActive("N");
    session.update(empDet);
}

public boolean doHardDelete(Employee emp) {
    empDet = session.get(Employee.class, emp.getId());
    session.delete(empDet);
}

НетНезависимо от того, сколько транзакционных таблиц будет добавлено с основной ссылкой tbl, мой код должен выполнять операции (мягкое / жесткое удаление) соответственно.

В моем случае каждый раз, когда новые транзакционные таблицы добавляются с основной ссылкой I 'я делаю проверки, так что я просто хочу пропустить метод isDataExist () и сделать соответствующие удаления, как я могу сделать это лучше?

Пожалуйста, помогите мне с правильным подходом сделать то же самое.

1 Ответ

1 голос
/ 23 октября 2019

В теле метода isDataExist() много повторяющегося кода, который сложно поддерживать и расширять (если вам нужно добавить еще 3 таблицы, размер кода удвоится). Кроме того, логика не является оптимальной, так как она будет проходить по всем таблицам, даже если результата первой достаточно для возврата true.

Вот упрощенная версия (обратите внимание, что у меня нет 't проверил код, и могут быть ошибки, но этого должно быть достаточно, чтобы объяснить концепцию):

public boolean isDataExist(Employee emp) {
    List<String> tableNames = List.of("Table1", "Table2", "Table3");

    for (String tableName : tableNames) {
        if (existsInTable(tableName, emp.getId())) {
            return true;
        }
    }

    return false;
}

private boolean existsInTable(String tableName, Long employeeId) {
    String query = String.format("SELECT count(*) FROM %s WHERE emp_id=:id", tableName);

    long count = (long)session
            .createQuery(query)
            .setParameter("id", employeeId)
            .getSingleResult();

    return count > 0;
}

isDataExist() содержит список всех имен таблиц и выполняет итерации по ним до первого успешного обращения ктребуемый Employee id, в этом случае возвращается true. Если метод не найден ни в одной таблице, метод возвращает false.

private boolean existsInTable(String tableName, Long employeeId) - вспомогательный метод, который выполняет фактический поиск employeeId в указанном tableName. Я изменил запрос так, чтобы он просто возвращал счетчик (0 или более) вместо реальных объектов сущности, поскольку они не требуются, и нет смысла их извлекать.


РЕДАКТИРОВАТЬ в ответ на «Второй подход»

Соответствует ли Second Approach требованиям? Если это так, то это «правильный подход» к проблеме. :)

Я бы реорганизовал метод deleteEmployeeDetails, чтобы либо вернуть boolean (если ожидается только два возможных результата), либо вернуть пользовательский Enum, так как использование String здесь некажется уместным.

В deleteEmployeeDetails есть повторяющийся код, и это никогда не будет хорошей вещью. Вы должны отделить логику, которая решает тип response от кода, который его строит, что облегчает отслеживание, отладку и расширение кода при необходимости.

Дайте мне знать, если вам нужен пример кодаиз приведенных выше идей.


РЕДАКТИРОВАТЬ # 2

Вот пример кода в соответствии с запросом.

Сначала мы определим Statusenum, который следует использовать в качестве типа возврата из методов MasterDao:

public enum Status {
    DELETE_SUCCESS("Success", "200", "True", "Record deleted successfully"),
    DELETE_FAIL("Fail", "200", "False", ""),
    DEACTIVATE_SUCCESS("Success", "200", "True", "Record deactivated successfully"),
    DEACTIVATE_FAIL("Fail", "200", "False", ""),
    ERROR("Fail", "500", "False", "");

    private String status;
    private String statusCode;
    private String result;
    private String reason;

    Status(String status, String statusCode, String result, String reason) {
        this.status = status;
        this.statusCode = statusCode;
        this.result = result;
        this.reason = reason;
    }

    // Getters 
}

MasterDao методы изменены для возврата Status вместо String или boolean:

public Status deleteEmployeeDetails(Employee employee) {
    return Status.DELETE_SUCCESS; // or Status.DELETE_FAIL
}

public Status deactivateEmployee(Employee employee) {
    return Status.DEACTIVATE_SUCCESS; // or Status.DEACTIVATE_FAIL
}

Вот новый метод deleteEmployee():

public Response deleteEmployee(Employee employee) {
    Status status;
    String reason = null;

    try {
        status = masterDao.deleteEmployeeDetails(employee);
    } catch (Exception e) {
        if (isConstraintViolationException(e)) {
            status = masterDao.deactivateEmployee(employee);
        } else {
            status = Status.ERROR;
            reason = "# EXCEPTION : " + e.getMessage();
        }
    }

    return buildResponse(status, reason);
}

Он использует два простых служебных метода (вы можете сделать их статическими или экспортировать в служебный класс, так как они не зависят от внутреннего состояния).

Первый проверяет, является ли основная причина выданного исключения ConstraintViolationException:

private boolean isConstraintViolationException(Throwable throwable) {
    Throwable root = throwable;
    while (root != null && !(root instanceof ConstraintViolationException)) {
        root = root.getCause();
    }
    return root != null;
}

А второй создает Response из Status и a reason:

private Response buildResponse(Status status, String reason) {
    Response response = new Response();
    response.setStatus(status.getStatus());
    response.setStatusCode(status.getStatusCode());
    response.setResult(status.getResult());

    if (reason != null) {
        response.setReason(reason);
    } else {
        response.setReason(status.getReason());
    }

    return response;
}

Если вам не нравится загружать Status enum сообщениями по умолчанию Response, вы можете удалитьэто из дополнительной информации:

public enum Status {
    DELETE_SUCCESS, DELETE_FAIL, DEACTIVATE_SUCCESS, DEACTIVATE_FAIL, ERROR;
}

И используйте операторы switch или if-else в buildResponse(Status status, String reason) методе для построения ответа на основе типа Status.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...