Ответ 1
По крайней мере, версия 2.0
Spring-Data-Jpa
модифицировала findOne()
.
Теперь findOne()
не имеет одинаковую подпись и одинаковое поведение.
Ранее это было определено в интерфейсе CrudRepository
как:
T findOne(ID primaryKey);
Теперь единственный findOne()
который вы найдете в CrudRepository
- это метод, который определен в интерфейсе QueryByExampleExecutor
как:
<S extends T> Optional<S> findOne(Example<S> example);
Наконец, это реализуется SimpleJpaRepository
, реализацией по CrudRepository
интерфейса CrudRepository
.
Этот метод является запросом по примеру поиска, и вы не хотите использовать его в качестве замены.
Фактически, метод с таким же поведением все еще присутствует в новом API, но имя метода изменилось.
Он был переименован из findOne()
в findById()
в интерфейсе CrudRepository
:
Optional<T> findById(ID id);
Теперь он возвращает Optional
. Что не так плохо, чтобы предотвратить исключение NullPointerException
.
Итак, фактический метод для вызова теперь является Optional<T> findById(ID id)
.
Как это использовать?
Обучение по Optional
. Вот важная информация о его спецификации:
Контейнерный объект, который может содержать или не содержать ненулевое значение. Если значение присутствует, isPresent() вернет true, а get() вернет значение.
Предоставляются дополнительные методы, которые зависят от наличия или отсутствия содержащегося в нем значения, например orElse() (возвращают значение по умолчанию, если значение отсутствует) и ifPresent() (выполняют блок кода, если значение присутствует).
Некоторые советы о том, как использовать Optional
с Optional<T> findById(ID id)
.
Обычно, когда вы ищете сущность по идентификатору, вы хотите вернуть ее или выполнить определенную обработку, если она не найдена.
Вот три классических примера использования.
1) Предположим, что если сущность найдена, вы хотите получить ее, иначе вы хотите получить значение по умолчанию.
Вы могли бы написать:
Foo foo = repository.findById(id)
.orElse(new Foo());
или получите null
значение по умолчанию, если оно имеет смысл (то же поведение, что и до изменения API):
Foo foo = repository.findById(id)
.orElse(null);
2) Предположим, что если сущность найдена, вы хотите вернуть ее, иначе вы хотите вызвать исключение.
Вы могли бы написать:
return repository.findById(id)
.orElseThrow(() -> new EntityNotFoundException(id));
3) Предположим, что вы хотите применить другую обработку в зависимости от того, найдена сущность или нет (без необходимости исключения).
Вы могли бы написать:
Optional<Foo> fooOptional = fooRepository.findById(id);
if (fooOptional.isPresent()){
Foo foo = fooOptional.get();
// processing with foo ...
}
else{
// alternative processing....
}