Repository navigation
реализовать add-bookings - #3
Conversation
| import javax.persistence.*; | ||
| import java.time.LocalDateTime; | ||
|
|
||
| @Data |
There was a problem hiding this comment.
equals и hashCode переопределять не нужно
| @Enumerated(EnumType.STRING) | ||
| private StatusOfBooking status; | ||
|
|
||
| public static Booking getValidatedBooking(BookingRepository bookingRepository, long bookingId) { |
There was a problem hiding this comment.
Репозиторий не должен внедряться в модель. Домен не должен зависеть от инфраструктурных единиц, это ядро приложения
| @GetMapping | ||
| public List<BookingDtoOut> getAllBookingByUser( | ||
| @RequestHeader(HeaderConstants.X_SHARER_USER_ID) long userId, | ||
| @RequestParam(required = false, defaultValue = HeaderConstants.DEFAULT_STATE_VALUE) |
There was a problem hiding this comment.
Если указано дефолтное значение, то required = false можно удалить, аналогично ниже
| if (item.getOwner().getId() == userId) { | ||
| throw new NotFoundException("Владелец не может бронировать свою вещь"); | ||
| } | ||
|
|
There was a problem hiding this comment.
Еще лучше проверить, что вещь не забронирована никем другим на запрашиваемые даты.
| private final BookingRepository bookingRepository; | ||
|
|
||
| @Override | ||
| @Transactional |
There was a problem hiding this comment.
@transactional можно вынести на уровень класса
Аналогично для остальных сервисов
There was a problem hiding this comment.
Я правильно понимаю, что когда я выношу @transactional на уровень класса, то для всех методов будут создаваться транзакции, но для методов гет все равно нужно будет явно указать @transactional(readOnly = true)
|
|
||
| List<Booking> findAllByBookerIdOrderByStartDesc(long userId); | ||
|
|
||
| @Query("select b from Booking b where b.booker.id = ?1 and ?2 between b.start and b.end order by b.start desc") |
There was a problem hiding this comment.
Можно обойтись без кастомных запросов с помощью query методов?)
There was a problem hiding this comment.
Попробую снова, но по мере выполнения ТЗ и пришла к таким разношерстным вариантам, так как иначе не получалось)
There was a problem hiding this comment.
Бинго! Это получилось, оказалось проще чем было в начале работы над ТЗ)
| import java.time.LocalDateTime; | ||
|
|
||
|
|
||
| @Data |
There was a problem hiding this comment.
equals и hashCode для модели переопределять нет необходимости
|
|
||
| import javax.persistence.*; | ||
|
|
||
| @Data |
There was a problem hiding this comment.
equals и hashCode для модели переопределять нет необходимости
Аналогично для остальных моделей
| private Boolean available; | ||
| private ItemRequest request; | ||
|
|
||
| public static Item getValidatedItem(ItemRepository itemRepository, long itemId) { |
There was a problem hiding this comment.
Репозиторий не должен внедряться в модель. Домен не должен зависеть от инфраструктурных единиц, это ядро приложения
Аналогично для остальных моделей
| .stream().map(ItemMapper::fromItemToDto) | ||
| List<Item> items = itemRepository.findALLByOwnerIdOrderByIdAsc(ownerId); | ||
| return items.stream().map(ItemMapper::fromItemToDto) | ||
| .peek(this::setLastBooking) |
There was a problem hiding this comment.
Проблема N+1 запроса. Необходимо получить все бронирования и комментарии одним запросом в БД, а не обращаться к репозиторию в каждой итерации )
…ений репоз-я в модели
| throw new NotFoundException("Владелец не может бронировать свою вещь"); | ||
| } | ||
| List<Booking> bookings = bookingRepository.findByItemIdAndStatus(item.getId(), StatusOfBooking.APPROVED); | ||
| boolean isConflicting = bookings.stream().anyMatch(booking -> |
There was a problem hiding this comment.
boolean isConflicting = !bookings.stream().allMatch(booking ->
!booking.getStart().isBefore(bookingDtoIn.getEnd()) || !booking.getEnd().isAfter(bookingDtoIn.getEnd())
);
| private final BookingRepository bookingRepository; | ||
|
|
||
| @Override | ||
| @Transactional |
| } | ||
|
|
||
| private void setCommentsForListItems(List<ItemDto> list) { | ||
| List<Comment> comments = commentRepository.findAll(); |
There was a problem hiding this comment.
Все комментарии выгружать не нужно. Можно выгрузить только по списку items
| .collect(Collectors.toList()); | ||
| list.forEach(itemDto -> { | ||
| List<CommentDto> itemComments = commentDtos.stream() | ||
| .filter(commentDto -> itemDto.getComments().contains(commentDto)) |
There was a problem hiding this comment.
А где заполняются комментарии в itemDto, чтобы условие itemDto.getComments().contains(commentDto) было когда-нибудь true?
| .map(CommentMapper::fromCommentToDto) | ||
| .collect(Collectors.toList()); | ||
| list.forEach(itemDto -> { | ||
| List<CommentDto> itemComments = commentDtos.stream() |
There was a problem hiding this comment.
Чтобы избавиться от вложенного цикла, лучше comments преобразовать в мапу, где ключ - itemId (или Item), а значение - список комментариев.
| .orElse(null); | ||
| Booking lastBooking = bookings.stream() | ||
| .filter(booking -> booking.getStart().isBefore(LocalDateTime.now())) | ||
| .max(Comparator.comparing(Booking::getEnd)) |
There was a problem hiding this comment.
Чтобы найти самое последнее бронирование, у next просто использовала findFirst, или лучше одинаково тогда использовать сортировку и там и там? Т.е для next это будет min(Comparator.comparing(Booking::getStart))
No description provided.