Skip to content
This repository was archived by the owner on Jan 28, 2026. It is now read-only.

Commit 04faa09

Browse files
author
ge85riz
committed
⚡️ perf: prefetch user profile authorities before returning seat generation algorithm results to reduce db round trips for each profile.authorities fetch operation
1 parent 6209f5f commit 04faa09

5 files changed

Lines changed: 36 additions & 19 deletions

File tree

backend/src/main/java/com/itestra/eep/repositories/EventRepository.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,43 @@ public interface EventRepository extends JpaRepository<Event, UUID> {
3737
@Query("SELECT e FROM Event e WHERE e.id = :id")
3838
Optional<Event> findByIdWithUpdateLock(@Param("id") UUID id);
3939

40+
// since we are using SeatAllocationDetailsDTO's constructor,
41+
// we cannot explicitly use @EntityGraph; therefore, we have to join profile.authorities.
4042
@Query("""
4143
SELECT new com.itestra.eep.dtos.SeatAllocationDetailsDTO(
42-
p.employee.profile,
44+
prof,
4345
p.id,
4446
CAST(null AS java.util.UUID),
4547
p.chair.id,
4648
CAST(null AS java.lang.String)
4749
)
4850
FROM Event e
4951
JOIN e.employeeParticipations p
52+
JOIN p.employee emp
53+
JOIN emp.profile prof
54+
LEFT JOIN FETCH prof.authorities
5055
WHERE e.id = :eventId
5156
5257
UNION
5358
5459
SELECT new com.itestra.eep.dtos.SeatAllocationDetailsDTO(
55-
v.profile,
60+
prof,
5661
v.id,
5762
v.invitor.id,
5863
v.chair.id,
5964
v.accessLink
6065
)
6166
FROM Event e
6267
JOIN e.visitorParticipations v
68+
JOIN v.profile prof
69+
LEFT JOIN FETCH prof.authorities
6370
WHERE e.id = :eventId
6471
""")
6572
List<SeatAllocationDetailsDTO> findCurrentSeatAllocationsByEventId(@Param("eventId") UUID eventId);
6673

6774

68-
@EntityGraph(attributePaths = {"employeeParticipations.employee.profile.authorities",
75+
@EntityGraph(attributePaths = {
76+
"employeeParticipations.employee.profile.authorities",
6977
"visitorParticipations.profile.authorities"})
7078
@Query("""
7179
SELECT p.employee.profile

backend/src/main/java/com/itestra/eep/repositories/custom/PreviousMatchesRepositoryCustom.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
@Repository
99
public interface PreviousMatchesRepositoryCustom {
1010

11-
void batchInsertPreviousMatches(List<PreviousMatch> matches);
11+
void batchInsertPreviousMatches(List<PreviousMatch.PreviousMatchId> matches);
1212

1313
}

backend/src/main/java/com/itestra/eep/repositories/custom/impl/PreviousMatchesRepositoryCustomImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class PreviousMatchesRepositoryCustomImpl implements PreviousMatchesRepos
1616
private final JdbcTemplate jdbcTemplate;
1717

1818
@Override
19-
public void batchInsertPreviousMatches(List<PreviousMatch> matches) {
19+
public void batchInsertPreviousMatches(List<PreviousMatch.PreviousMatchId> matches) {
2020
if (matches.isEmpty()) {
2121
return;
2222
}
@@ -29,10 +29,10 @@ public void batchInsertPreviousMatches(List<PreviousMatch> matches) {
2929
""";
3030

3131
jdbcTemplate.batchUpdate(sql, matches, matches.size(),
32-
(PreparedStatement ps, PreviousMatch match) -> {
33-
ps.setObject(1, match.getId().getFirstEmployeeId());
34-
ps.setObject(2, match.getId().getSecondEmployeeId());
35-
ps.setObject(3, match.getId().getEventId());
32+
(PreparedStatement ps, PreviousMatch.PreviousMatchId match) -> {
33+
ps.setObject(1, match.getFirstEmployeeId());
34+
ps.setObject(2, match.getSecondEmployeeId());
35+
ps.setObject(3, match.getEventId());
3636
});
3737
}
3838

backend/src/main/java/com/itestra/eep/services/impl/SeatAllocationServiceImpl.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,20 @@ private void persistNewEmployeePreviousMatches(UUID eventId, UUID[] neighborProf
9696
}
9797

9898
UUID employeeId = employeeParticipation.get().getEmployee().getId();
99-
List<PreviousMatch> newPreviousMatches = calculateBidirectionalMatches(employeeId, neighborProfileIds, eventId);
99+
List<PreviousMatch.PreviousMatchId> newPreviousMatches = calculateBidirectionalMatches(employeeId, neighborProfileIds, eventId);
100100

101101
if (!newPreviousMatches.isEmpty()) {
102102
previousMatchesRepository.batchInsertPreviousMatches(newPreviousMatches);
103103
}
104104
}
105105

106-
private List<PreviousMatch> calculateBidirectionalMatches(UUID employeeId, UUID[] neighborIds, UUID eventId) {
107-
List<PreviousMatch> matches = new ArrayList<>(neighborIds.length * 2);
106+
private List<PreviousMatch.PreviousMatchId> calculateBidirectionalMatches(UUID employeeId, UUID[] neighborIds, UUID eventId) {
107+
List<PreviousMatch.PreviousMatchId> matches = new ArrayList<>(neighborIds.length * 2);
108108

109109
for (UUID neighborId : neighborIds) {
110110
// we create bidirectional matches here
111-
matches.add(new PreviousMatch(new PreviousMatch.PreviousMatchId(employeeId, neighborId, eventId)));
112-
matches.add(new PreviousMatch(new PreviousMatch.PreviousMatchId(neighborId, employeeId, eventId)));
111+
matches.add(new PreviousMatch.PreviousMatchId(employeeId, neighborId, eventId));
112+
matches.add(new PreviousMatch.PreviousMatchId(neighborId, employeeId, eventId));
113113
}
114114

115115
return matches;
@@ -118,6 +118,12 @@ private List<PreviousMatch> calculateBidirectionalMatches(UUID employeeId, UUID[
118118

119119
@Override
120120
public void performTableBasedSeatAllocation(UUID eventId, StageMapDTO stageMap) throws IOException, InterruptedException {
121+
122+
// Delete all previous matches for this event before we start calculating for a clean state
123+
// in case of any exception, they will be rolled back of course.
124+
previousMatchesRepository.deleteAllByEventId(eventId);
125+
previousMatchesRepository.flush();
126+
121127
Event event = eventRepository.findByIdJoinedWithPreviousMatches(eventId).orElseThrow(EventNotFoundException::new);
122128

123129
List<EmployeeParticipation> employeeParticipations = event.getEmployeeParticipations().stream().toList();
@@ -224,20 +230,18 @@ private void persistNewChairAssignments(UUID eventId, List<Chair> chairsToPersis
224230
}
225231

226232
private void persistPreviousMatchesDueToNewMatchings(UUID eventId, Map<UUID, List<UUID>> tableToEmployeesMap) {
227-
// Delete all previous matches for this event
228-
previousMatchesRepository.deleteAllByEventId(eventId);
229233

230234
// Create new previous matches for employees seated at the same table
231-
List<PreviousMatch> newPreviousMatches = new ArrayList<>();
235+
List<PreviousMatch.PreviousMatchId> newPreviousMatches = new ArrayList<>();
232236

233237
// Create pairs for each table
234238
tableToEmployeesMap.values().forEach(employeesAtTable -> {
235239
for (int i = 0; i < employeesAtTable.size(); i++) {
236240
for (int j = i + 1; j < employeesAtTable.size(); j++) {
237241
UUID employeeId1 = employeesAtTable.get(i);
238242
UUID employeeId2 = employeesAtTable.get(j);
239-
newPreviousMatches.add(new PreviousMatch(new PreviousMatch.PreviousMatchId(employeeId1, employeeId2, eventId)));
240-
newPreviousMatches.add(new PreviousMatch(new PreviousMatch.PreviousMatchId(employeeId2, employeeId1, eventId)));
243+
newPreviousMatches.add(new PreviousMatch.PreviousMatchId(employeeId1, employeeId2, eventId));
244+
newPreviousMatches.add(new PreviousMatch.PreviousMatchId(employeeId2, employeeId1, eventId));
241245
}
242246
}
243247
});

backend/src/main/java/com/itestra/eep/sql/ddl.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ CREATE INDEX idx_visitor_participation_event_profile ON organization.visitor_par
152152
CREATE INDEX idx_visitor_participation_invitor ON organization.visitor_participation (invitor_participation_id) WHERE invitor_participation_id IS NOT NULL;
153153
CREATE INDEX idx_visitor_participation_access_link ON organization.visitor_participation (access_link);
154154
--
155+
CREATE INDEX idx_previous_matches_first_employee ON organization.previous_matches (first_employee_id);
156+
CREATE INDEX idx_previous_matches_second_employee ON organization.previous_matches (second_employee_id);
157+
CREATE INDEX idx_previous_matches_event ON organization.previous_matches (event_id);
158+
CREATE INDEX idx_previous_matches_event_employees ON organization.previous_matches (first_employee_id, second_employee_id, event_id);
159+
--
155160
CREATE INDEX idx_files_event_id ON organization.files (event_id);
156161
CREATE INDEX idx_files_name ON organization.files (name);
157162
--

0 commit comments

Comments
 (0)