Skip to content

реализовать add-bookings - #3

Merged
biscuitka merged 4 commits into
mainfrom
add-bookings
Aug 3, 2023
Merged

biscuitka merged 4 commits into
mainfrom
add-bookings

Conversation

@biscuitka

Copy link
Copy Markdown
Owner

No description provided.

import javax.persistence.*;
import java.time.LocalDateTime;

@Data

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

equals и hashCode переопределять не нужно

@Enumerated(EnumType.STRING)
private StatusOfBooking status;

public static Booking getValidatedBooking(BookingRepository bookingRepository, long bookingId) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Репозиторий не должен внедряться в модель. Домен не должен зависеть от инфраструктурных единиц, это ядро приложения

@GetMapping
public List<BookingDtoOut> getAllBookingByUser(
@RequestHeader(HeaderConstants.X_SHARER_USER_ID) long userId,
@RequestParam(required = false, defaultValue = HeaderConstants.DEFAULT_STATE_VALUE)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если указано дефолтное значение, то required = false можно удалить, аналогично ниже

if (item.getOwner().getId() == userId) {
throw new NotFoundException("Владелец не может бронировать свою вещь");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Еще лучше проверить, что вещь не забронирована никем другим на запрашиваемые даты.

private final BookingRepository bookingRepository;

@Override
@Transactional

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@transactional можно вынести на уровень класса
Аналогично для остальных сервисов

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я правильно понимаю, что когда я выношу @transactional на уровень класса, то для всех методов будут создаваться транзакции, но для методов гет все равно нужно будет явно указать @transactional(readOnly = true)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да


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")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно обойтись без кастомных запросов с помощью query методов?)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Попробую снова, но по мере выполнения ТЗ и пришла к таким разношерстным вариантам, так как иначе не получалось)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Бинго! Это получилось, оказалось проще чем было в начале работы над ТЗ)

import java.time.LocalDateTime;


@Data

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

equals и hashCode для модели переопределять нет необходимости


import javax.persistence.*;

@Data

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

equals и hashCode для модели переопределять нет необходимости
Аналогично для остальных моделей

private Boolean available;
private ItemRequest request;

public static Item getValidatedItem(ItemRepository itemRepository, long itemId) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Репозиторий не должен внедряться в модель. Домен не должен зависеть от инфраструктурных единиц, это ядро приложения
Аналогично для остальных моделей

.stream().map(ItemMapper::fromItemToDto)
List<Item> items = itemRepository.findALLByOwnerIdOrderByIdAsc(ownerId);
return items.stream().map(ItemMapper::fromItemToDto)
.peek(this::setLastBooking)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Проблема N+1 запроса. Необходимо получить все бронирования и комментарии одним запросом в БД, а не обращаться к репозиторию в каждой итерации )

throw new NotFoundException("Владелец не может бронировать свою вещь");
}
List<Booking> bookings = bookingRepository.findByItemIdAndStatus(item.getId(), StatusOfBooking.APPROVED);
boolean isConflicting = bookings.stream().anyMatch(booking ->

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boolean isConflicting = !bookings.stream().allMatch(booking ->
!booking.getStart().isBefore(bookingDtoIn.getEnd()) || !booking.getEnd().isAfter(bookingDtoIn.getEnd())
);

private final BookingRepository bookingRepository;

@Override
@Transactional

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да

}

private void setCommentsForListItems(List<ItemDto> list) {
List<Comment> comments = commentRepository.findAll();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Все комментарии выгружать не нужно. Можно выгрузить только по списку items

.collect(Collectors.toList());
list.forEach(itemDto -> {
List<CommentDto> itemComments = commentDtos.stream()
.filter(commentDto -> itemDto.getComments().contains(commentDto))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А где заполняются комментарии в itemDto, чтобы условие itemDto.getComments().contains(commentDto) было когда-нибудь true?

.map(CommentMapper::fromCommentToDto)
.collect(Collectors.toList());
list.forEach(itemDto -> {
List<CommentDto> itemComments = commentDtos.stream()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Чтобы избавиться от вложенного цикла, лучше comments преобразовать в мапу, где ключ - itemId (или Item), а значение - список комментариев.

.orElse(null);
Booking lastBooking = bookings.stream()
.filter(booking -> booking.getStart().isBefore(LocalDateTime.now()))
.max(Comparator.comparing(Booking::getEnd))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему сортировка по end?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Чтобы найти самое последнее бронирование, у next просто использовала findFirst, или лучше одинаково тогда использовать сортировку и там и там? Т.е для next это будет min(Comparator.comparing(Booking::getStart))

@biscuitka
biscuitka merged commit 690808a into main Aug 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants