Некорректная работа с условиями

Программа должна узнавать на определённую дату забронирована квартира или нет, если нет, то бронируем, если да, то вывести сообщение, что она забронирована. Как работает моя программа:

Первый прогон: делаем Post-запрос с информацией, что хотим забронировать на 2020-03-12 по 2020-03-19. Программа сохраняет. Если сделаем ещё один точно такой же запрос, то программа снова сохраняет информацию.

Второй прогон: делаем Post-запрос с информацией, что хотим забронировать на 2020-03-12 по 2020-03-19. Программа пишет, что квартира уже занята. Делаем новый Post-запрос, что хотим забронировать на 2020-04-12 по 2020-04-19, программа сохраняет информацию. Если сделаем ещё один точно такой же запрос, то программа снова сохранит.

Как реализован запрос в БД: ищем в БД Contract по id House и end_date позже, чем start_date у нового Contract. Таким образом можно будет найти либо действующий Contract, либо отсутствующий, в случае если отсутствует, то можно создать новый.

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

В чём проблема: как мне правильно выстроить условие, что корректно сохранялись данные? Потому что повторного сохранения не должно быть на одну и ту же дату.

Контроллер:

@PostMapping("/rent")
@PreAuthorize("hasAuthority('user:write')")
public String homeRent(@RequestBody ContractDto contractDto) {
    List<Contract> con = contractService.findContractByHouseIdAndEndDateAfter(contractDto.getHouseId(), contractDto.getEndDate());
    if(con.isEmpty()) {
        Contract contract = new Contract();
        contract.setHouse(houseService.findById(contractDto.getHouseId()));
        contract.setUser(userService.findById(contractDto.getTenantId()));
        contract.setStartDate(contractDto.getStartDate());
        contract.setEndDate(contractDto.getEndDate());
        contractService.save(contract);
        return "Квартира забронирована";
    }
    return "Квартира занята";
}

Репо

@Repository
public interface ContractRepository extends JpaRepository<Contract, Long> {
    List<Contract> findContractByHouseIdAndEndDateAfter(Long houseId, LocalDate from);
}

Ответы (1 шт):

Автор решения: AlekseiGaile
@Query(value = "select * from contract 
WHERE id = :houseId
  and visit_date > :startDate
  and visit_date < cast(:endDay as date) + interval '1' day", nativeQuery = true)
List<Contract> findAllByDate(@Param("houseId") Long houseId, @Param("startDate") LocalDate startDate, @Param("endDay") LocalDate endDay);

Предположу, что в данной реализации приложения надо смотреть промежуток дат на который клиент хочет зарезервировать номер. Если данный запрос что то возвращает, то запрос не должен сохранять контракт в БД, если он возвращает null, тогда создаем новый контракт.

→ Ссылка