it-swarm.com.ru

Почему getOne (…) в репозитории Spring Data не вызывает исключение EntityNotFoundException?

Я работаю над странной проблемой, я проводил интеграционное тестирование, вызывая свой контроллер, чтобы получить объект из базы данных, которая не существует.

public Optional<T> get(Long id) {

  try {
    return Optional.ofNullable(repository.getOne(id));
  } catch(EntityNotFoundException e) {
    return Optional.empty();
  }
}

Когда getOne(…) не может ничего найти, я ожидал EntityNotFoundException, но на самом деле ничего. Если я проверю свой результат, я увижу, что у меня есть пустая сущность со ссылкой на нее обработчика "threw EntityNotFoundException", но мы не идем в ловушку, и я возвращаю необязательную для этой странной сущности.

Я не могу понять это поведение.

18
Seb

Это связано с тем, что JPA определяет EntityManager.getReference(…) для работы. Он должен возвращать прокси, который либо разрешит объект, который будет возвращен при первом доступе к свойству, либо, в конце концов, сгенерирует содержащееся в нем исключение.

Самый простой способ обойти это - просто использовать вместо него findOne(…), например, Optional.ofNullable(repository.findOne(…)). findOne(…) вернет null, если результат не найден.

Более продвинутый способ решения этой проблемы - сделать так, чтобы хранилище возвращало экземпляры Optional напрямую. Это может быть достигнуто путем создания настраиваемого интерфейса базового репозитория с использованием Optional<T> в качестве типа возврата для методов find…-.

interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {

  Optional<T> findOne(ID id);

  // declare additional methods if needed
}

interface YourRepository extends BaseRepository<DomainClass, Long> { … }

Найдите полный пример этого в хранилище примеров Spring Data .

26
Oliver Drotbohm

Вот как это работает для меня

public User findUserById(Long id) {
    return userRepository.findById(id).orElse(null);
}
0
VK321