Как проверить есть ли строка с функцией getOne - PullRequest
1 голос
/ 22 февраля 2020

Предположим, что «Проект» - это POJO. На служебном уровне моего проекта я написал функцию, которая получает строку из таблицы.

@Override
public ProjectDto getAProject(Long id) {
    try {
        Project project = projectRepository.getOne(id);
        if (project==null) {
            throw new IllegalArgumentException("Project not found");
        } else {
            return modelMapper.map(project, ProjectDto.class);
        }
    } catch (EntityNotFoundException ex) {
        throw new IllegalArgumentException("Project not found");
    }
}

Функция работает нормально с уже существующими значениями идентификатора. Но если я даю несуществующее значение, возникает исключение, подобное следующему. Похоже, что функция «getOne ()» не генерирует исключение «EntityNotFoundException».

ModelMapper mapping errors: Error mapping com.issuemanagement.entity.Project to com.issuemanagement.dto.ProjectDto

, что означает, что исключение исходит из логики отображения модели c. Потому что объект "project" заполнен нулевыми значениями, поэтому не может отображаться в класс DTO. Я изменил функцию следующим образом, чтобы исправить это.

@Override
public ProjectDto getAProject(Long id) {
    boolean isExist = projectRepository.existsById(id);
    if (isExist) {
        Project project = projectRepository.getOne(id);
        return modelMapper.map(project, ProjectDto.class);
    } else {
        throw new IllegalArgumentException("Project not found");
    }
}

но при этом программа дважды попадает в БД. Мне это не нравится Как я могу сделать эту операцию только с одной транзакцией?

Кстати, если я пытаюсь запустить функцию "проекта" toString (), она выдает "EntityNotFoundException", но это выглядит как не официальный путь. или это так? Я надеюсь, что где-то должна быть логическая переменная.

1 Ответ

2 голосов
/ 23 февраля 2020

getOne() на JpaRepository вызовет getReference() на EntityManager под капотом, который вернет экземпляр, состояние которого лениво выбирается. EntityNotFoundException не сработает сразу, а только быть брошенным, когда к его состоянию обращаются в первый раз.

Обычно используется в том случае, когда вам нужно настроить отношение @ManyToOne для объекта (скажем, настроить Отдел для сотрудника), но у вас просто есть идентификатор соответствующего объекта (например, DepartmentId). Использование getOne() позволяет вам получить экземпляр прокси-сервера Department таким образом, что вам на самом деле не нужно запрашивать базу данных, чтобы получить фактический экземпляр Department только для установки его отношения для Employee.

В вашем случае вы следует использовать findById(), который вернет пустой Optional, если экземпляр не существует:

@Override
public ProjectDto getAProject(Long id) {
   Project project = projectRepository.findById(id)
                    .orElseThrow(()->new IllegalArgumentException("Project not found"));

  return modelMapper.map(project, ProjectDto.class);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...