Skip to content

Commit 50add41

Browse files
authored
Merge pull request #45 from TP-RENTPLACE/feature/(TP-111)-optimise-db-queries
Feature/(tp 111) optimise db queries
2 parents 02369e5 + adb0268 commit 50add41

9 files changed

Lines changed: 152 additions & 14 deletions

File tree

rentplace/src/main/java/kattsyn/dev/rentplace/controllers/FavouritesController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public ResponseEntity<Void> addPropertyToFavourites(@PathVariable long id, Authe
5858
}
5959

6060
@Operation(
61-
summary = "Добавить объявление в избранное"
61+
summary = "Удалить объявление из избранного"
6262
)
6363
@ApiResponses(value = {
6464
@ApiResponse(responseCode = "204", description = "Успешно. Без тела ответа", content = @Content),

rentplace/src/main/java/kattsyn/dev/rentplace/entities/Property.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ NOT PUBLISHED (не опубликовано) - объявление уже пр
8282
private User owner;
8383

8484
@Schema(description = "Фотографии жилья")
85-
@OneToMany(fetch=FetchType.EAGER)
85+
@OneToMany(fetch=FetchType.LAZY)
8686
@JoinTable(name = "properties_images",
8787
joinColumns = @JoinColumn(name = "property_id"),
8888
inverseJoinColumns = @JoinColumn(name = "image_id")
8989
)
9090
private Set<Image> images = new HashSet<>();
9191

9292
@Schema(description = "Категории жилья")
93-
@ManyToMany(fetch = FetchType.EAGER)
93+
@ManyToMany(fetch = FetchType.LAZY)
9494
@JoinTable(
9595
name = "properties_categories",
9696
joinColumns = @JoinColumn(name = "property_id"),
@@ -99,7 +99,7 @@ NOT PUBLISHED (не опубликовано) - объявление уже пр
9999
private Set<Category> categories = new HashSet<>();
100100

101101

102-
@ManyToMany(fetch=FetchType.EAGER)
102+
@ManyToMany(fetch=FetchType.LAZY)
103103
@JoinTable(
104104
name = "properties_facilities",
105105
joinColumns = @JoinColumn(name = "property_id"),

rentplace/src/main/java/kattsyn/dev/rentplace/exceptions/GlobalExceptionHandler.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package kattsyn.dev.rentplace.exceptions;
22

3+
import io.jsonwebtoken.ExpiredJwtException;
34
import jakarta.security.auth.message.AuthException;
45
import jakarta.servlet.http.HttpServletRequest;
56
import kattsyn.dev.rentplace.dtos.ErrorResponse;
@@ -55,6 +56,17 @@ public ResponseEntity<ErrorResponse> handleValidationExceptions(AuthException ex
5556
return new ResponseEntity<>(response, HttpStatus.UNAUTHORIZED);
5657
}
5758

59+
@ExceptionHandler(ExpiredJwtException.class)
60+
public ResponseEntity<ErrorResponse> handleValidationExceptions(ExpiredJwtException ex, WebRequest request) {
61+
ErrorResponse response = new ErrorResponse(
62+
HttpStatus.UNAUTHORIZED.value(),
63+
"JSON WEB TOKEN EXPIRED",
64+
ex.getMessage(),
65+
request.getDescription(false).replace("uri=", "")
66+
);
67+
return new ResponseEntity<>(response, HttpStatus.UNAUTHORIZED);
68+
}
69+
5870
@ExceptionHandler(Exception.class)
5971
public ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex, WebRequest request) {
6072
String path = "";

rentplace/src/main/java/kattsyn/dev/rentplace/repositories/PropertyRepository.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,52 @@
44
import kattsyn.dev.rentplace.entities.Property;
55
import org.springframework.data.jpa.repository.JpaRepository;
66
import org.springframework.data.jpa.repository.Query;
7+
import org.springframework.data.repository.query.Param;
78

89
import java.util.List;
10+
import java.util.Optional;
911

1012
public interface PropertyRepository extends JpaRepository<Property, Long> {
1113

1214
@Query("""
1315
SELECT DISTINCT p
1416
FROM Property p
15-
LEFT JOIN FETCH p.categories
16-
LEFT JOIN FETCH p.facilities
17+
LEFT JOIN FETCH p.owner o
18+
LEFT JOIN FETCH p.categories c
19+
LEFT JOIN FETCH p.facilities f
1720
LEFT JOIN FETCH p.images
21+
LEFT JOIN FETCH o.image
22+
LEFT JOIN FETCH c.image
23+
LEFT JOIN FETCH f.image
1824
""")
1925
List<Property> findAllWithRelations();
2026

21-
List<Property> findAllByOwnerEmail(String email);
27+
@Query("""
28+
SELECT DISTINCT p
29+
FROM Property p
30+
LEFT JOIN FETCH p.owner o
31+
LEFT JOIN FETCH p.categories c
32+
LEFT JOIN FETCH p.facilities f
33+
LEFT JOIN FETCH p.images
34+
LEFT JOIN FETCH o.image
35+
LEFT JOIN FETCH c.image
36+
LEFT JOIN FETCH f.image
37+
WHERE p.owner.email = :email
38+
""")
39+
List<Property> findAllByOwnerEmail(@Param("email") String email);
40+
41+
@Query("""
42+
SELECT DISTINCT p
43+
FROM Property p
44+
LEFT JOIN FETCH p.owner o
45+
LEFT JOIN FETCH p.categories c
46+
LEFT JOIN FETCH p.facilities f
47+
LEFT JOIN FETCH p.images
48+
LEFT JOIN FETCH o.image
49+
LEFT JOIN FETCH c.image
50+
LEFT JOIN FETCH f.image
51+
WHERE p.propertyId = :id
52+
""")
53+
Optional<Property> findById(@Param("id") long id);
2254

2355
}

rentplace/src/main/java/kattsyn/dev/rentplace/repositories/ReservationRepository.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,50 @@
22

33
import kattsyn.dev.rentplace.entities.Reservation;
44
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.data.jpa.repository.Query;
6+
import org.springframework.data.repository.query.Param;
57

68
import java.util.List;
9+
import java.util.Optional;
710

811
public interface ReservationRepository extends JpaRepository<Reservation, Long> {
912

10-
List<Reservation> findAllByRenterEmail(String email);
13+
@Query("""
14+
SELECT DISTINCT r from Reservation r
15+
LEFT JOIN FETCH r.property p
16+
LEFT JOIN FETCH r.renter
17+
LEFT JOIN FETCH p.images
18+
LEFT JOIN FETCH p.owner
19+
LEFT JOIN FETCH p.facilities
20+
LEFT JOIN FETCH p.categories
21+
"""
22+
)
23+
List<Reservation> findAllWithRelations();
24+
25+
@Query("""
26+
SELECT DISTINCT r from Reservation r
27+
LEFT JOIN FETCH r.property p
28+
LEFT JOIN FETCH r.renter
29+
LEFT JOIN FETCH p.images
30+
LEFT JOIN FETCH p.owner
31+
LEFT JOIN FETCH p.facilities
32+
LEFT JOIN FETCH p.categories
33+
WHERE r.renter.email = :email
34+
"""
35+
)
36+
List<Reservation> findAllByRenterEmail(@Param("email") String email);
37+
38+
@Query("""
39+
SELECT DISTINCT r from Reservation r
40+
LEFT JOIN FETCH r.property p
41+
LEFT JOIN FETCH r.renter
42+
LEFT JOIN FETCH p.images
43+
LEFT JOIN FETCH p.owner
44+
LEFT JOIN FETCH p.facilities
45+
LEFT JOIN FETCH p.categories
46+
WHERE r.reservationId = :reservationId
47+
"""
48+
)
49+
Optional<Reservation> findById(@Param("reservationId") long reservationId);
1150

1251
}

rentplace/src/main/java/kattsyn/dev/rentplace/repositories/UserRepository.java

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,56 @@
22

33
import kattsyn.dev.rentplace.entities.User;
44
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.data.jpa.repository.Query;
6+
import org.springframework.data.repository.query.Param;
57

8+
import java.util.List;
69
import java.util.Optional;
710

811
public interface UserRepository extends JpaRepository<User, Long> {
912

10-
Optional<User> findByEmail(String email);
11-
boolean existsByEmail(String email);
1213

14+
@Query("""
15+
SELECT DISTINCT u FROM User u
16+
LEFT JOIN FETCH u.image
17+
LEFT JOIN FETCH u.favourites f
18+
LEFT JOIN FETCH f.categories c
19+
LEFT JOIN FETCH f.facilities fac
20+
LEFT JOIN FETCH f.owner o
21+
LEFT JOIN FETCH f.images
22+
LEFT JOIN FETCH c.image
23+
LEFT JOIN FETCH fac.image
24+
LEFT JOIN FETCH o.image
25+
""")
26+
List<User> findAllWithRelations();
27+
28+
@Query("""
29+
SELECT DISTINCT u FROM User u
30+
LEFT JOIN FETCH u.image
31+
LEFT JOIN FETCH u.favourites f
32+
LEFT JOIN FETCH f.categories c
33+
LEFT JOIN FETCH f.facilities fac
34+
LEFT JOIN FETCH f.owner o
35+
LEFT JOIN FETCH f.images
36+
LEFT JOIN FETCH c.image
37+
LEFT JOIN FETCH fac.image
38+
LEFT JOIN FETCH o.image
39+
WHERE u.userId = :userId
40+
""")
41+
Optional<User> findById(@Param("userId") long userId);
42+
43+
@Query("""
44+
SELECT DISTINCT u FROM User u
45+
LEFT JOIN FETCH u.image
46+
LEFT JOIN FETCH u.favourites f
47+
LEFT JOIN FETCH f.categories c
48+
LEFT JOIN FETCH f.facilities fac
49+
LEFT JOIN FETCH f.owner o
50+
LEFT JOIN FETCH f.images
51+
LEFT JOIN FETCH c.image
52+
LEFT JOIN FETCH fac.image
53+
LEFT JOIN FETCH o.image
54+
WHERE u.email = :email
55+
""")
56+
Optional<User> findByEmail(@Param("email") String email);
1357
}

rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/ReservationServiceImpl.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public boolean ownsReservationOrAdmin(long reservationId, String email) {
4848
}
4949

5050
@Override
51+
@Transactional
5152
public boolean allowedToCreateReservationOrAdmin(ReservationCreateEditDTO reservationCreateEditDTO, String email) {
5253
User user = userService.getUserByEmail(email);
5354

@@ -58,28 +59,33 @@ public boolean allowedToCreateReservationOrAdmin(ReservationCreateEditDTO reserv
5859
}
5960

6061
@Override
62+
@Transactional
6163
public List<ReservationDTO> findAllReservations() {
62-
return reservationMapper.fromReservations(reservationRepository.findAll());
64+
return reservationMapper.fromReservations(reservationRepository.findAllWithRelations());
6365
}
6466

6567
@Override
68+
@Transactional
6669
public List<ReservationDTO> findAllReservationsByRenterEmail(String email) {
6770
return reservationMapper.fromReservations(reservationRepository.findAllByRenterEmail(email));
6871
}
6972

7073
@Override
74+
@Transactional
7175
public Reservation getReservationById(long reservationId) {
7276
return reservationRepository.findById(reservationId).orElseThrow(
7377
() -> new NotFoundException(String.format("Reservation not found with id: %d", reservationId))
7478
);
7579
}
7680

7781
@Override
82+
@Transactional
7883
public ReservationDTO getReservationDTOById(long reservationId) {
7984
return reservationMapper.fromReservation(getReservationById(reservationId));
8085
}
8186

8287
@Override
88+
@Transactional
8389
public ReservationDTO createReservation(ReservationCreateEditDTO reservationCreateEditDTO) {
8490
Reservation reservation = reservationMapper.fromReservationCreateEditDTO(reservationCreateEditDTO);
8591
setPrices(reservation);
@@ -89,6 +95,7 @@ public ReservationDTO createReservation(ReservationCreateEditDTO reservationCrea
8995
}
9096

9197
@Override
98+
@Transactional
9299
public ReservationDTO updateReservation(long reservationId, ReservationCreateEditDTO reservationCreateEditDTO) {
93100
Reservation reservation = getReservationById(reservationId);
94101
Reservation updatedReservation = reservationMapper.fromReservationCreateEditDTO(reservationCreateEditDTO);
@@ -99,6 +106,7 @@ public ReservationDTO updateReservation(long reservationId, ReservationCreateEdi
99106
}
100107

101108
@Override
109+
@Transactional
102110
public ReservationDTO deleteById(long reservationId) {
103111
Reservation reservation = getReservationById(reservationId);
104112
reservationRepository.delete(reservation);

rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/UserServiceImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class UserServiceImpl implements UserService {
3131
@Transactional
3232
@Override
3333
public List<UserDTO> findAll() {
34-
return userMapper.fromUsers(userRepository.findAll());
34+
return userMapper.fromUsers(userRepository.findAllWithRelations());
3535
}
3636

3737
@Transactional
@@ -44,7 +44,7 @@ public User getUserByEmail(String email) {
4444

4545
@Override
4646
public boolean existsByEmail(String email) {
47-
return userRepository.existsByEmail(email);
47+
return userRepository.findByEmail(email).isPresent();
4848
}
4949

5050
@Override

rentplace/src/main/resources/db/migration/V202505090054__favourites_init.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ create table favourites
55
PRIMARY KEY (user_id, property_id),
66
FOREIGN KEY (user_id) references users (user_id) ON DELETE CASCADE,
77
FOREIGN KEY (property_id) references properties (property_id) ON DELETE CASCADE
8-
)
8+
);
9+
10+
CREATE INDEX idx_favourites_property ON favourites (property_id);
11+
CREATE INDEX idx_favourites_user ON favourites (user_id);

0 commit comments

Comments
 (0)