У меня есть следующий репозиторий:
@Repository
public interface EntityRepository extends JpaRepository<Entity, Long> {
List<Entity> findAllByFirstId(Long firstId);
List<Entity> findAllBySecondId(Long secondId);
List<Entity> findAllByFirstIdAndSecondId(Long firstId, Long secondId);
}
Конструктор, реализующий интерфейс, сгенерированный с помощью io.swagger:swagger-codegen-maven-plugin
, использует Optional<Long>
в качестве необязательных параметров запроса (базовый сервис использует также те же параметры):
ResponseEntity<List<Entity>> entities(Optional<Long> firstId, Optional<Long> secondId);
Я хотел бы отфильтровать сущности на основе параметров firstId
и secondId
, которые никогда не равны null
s в базе данных, но могут быть переданы через конструктор (параметр для поиска является необязательным).
Проблема возникает с именованными запросами, когда null
передается в качестве необязательного параметра, JpaReposotory
использует null
в качестве критерия поиска в базе данных. Это то, что я не хочу - я хочу игнорировать фильтрацию на основе этого параметра, пока он null
.
Мое обходное решение на основе Optional
:
public List<Entity> entities(Optional<Long> firstId, Optional<Long> secondId) {
return firstId
.or(() -> secondId)
.map(value -> {
if (firstId.isEmpty()) {
return entityRepository.findAllBySecondId(value);
}
if (secondId.isEmpty()) {
return entityRepository.findAllByFirstId(value);
}
return entityRepository.findAllByFirstIdAndSecondId(
firstId.get(), secondId.get());
})
.orElse(entityRepository.findAll())
.stream()
.map(...) // Mapping between DTO and entity. For sake of brevity
// I used the same onject Entity for both controler and repository
// as long as it not related to the question
.collect(Collectors.toList());
}
Эта проблема уже была задана: Spring Data - игнорировать параметр, если он имеет нулевое значение и создан тикет DATAJPA-209 .
Пока Вопросу уже почти 3 года, а билет относится к 2012 году. Я хотел бы спросить, существует ли более удобный и универсальный способ избежать накладных расходов на обработку Optional
и дублирование методов репозитория. Решение для 2 таких параметров выглядит приемлемым, однако я бы хотел применить ту же самую фильтрацию для 4-5 параметров.