diff --git a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemRepository.java b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemRepository.java index 666681e6..a1b3baee 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemRepository.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemRepository.java @@ -29,4 +29,13 @@ public interface JourneyItemRepository extends JpaRepository /** COUNT for the 100-item cap check — COUNT(*)-based, never MAX(position)-derived. */ long countByGeschichteId(UUID geschichteId); + + /** + * Loads journey items with their linked Document in a single JOIN FETCH query, + * eliminating the N+1 SELECT that would occur when accessing item.getDocument() + * lazily for each item. Items without a document (note-only) are included via + * LEFT JOIN. Ordered by position ASC. + */ + @Query("SELECT ji FROM JourneyItem ji LEFT JOIN FETCH ji.document WHERE ji.geschichte.id = :geschichteId ORDER BY ji.position ASC") + List findByGeschichteIdWithDocument(@Param("geschichteId") UUID geschichteId); } diff --git a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemService.java b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemService.java index 4e0a78d8..38259047 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemService.java @@ -183,7 +183,7 @@ public class JourneyItemService { } public List getItems(UUID geschichteId) { - return journeyItemRepository.findByGeschichteIdOrderByPosition(geschichteId) + return journeyItemRepository.findByGeschichteIdWithDocument(geschichteId) .stream().map(this::toView).toList(); } @@ -206,8 +206,8 @@ public class JourneyItemService { JourneyItemView toView(JourneyItem item) { DocumentSummary docSummary = null; - if (item.getDocumentId() != null) { - Document doc = documentService.getSummaryById(item.getDocumentId()); + Document doc = item.getDocument(); + if (doc != null) { docSummary = toSummary(doc); } return new JourneyItemView(item.getId(), item.getPosition(), docSummary, item.getNote()); diff --git a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemServiceTest.java b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemServiceTest.java index 15ebcd87..d7b31be7 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemServiceTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/journeyitem/JourneyItemServiceTest.java @@ -322,7 +322,6 @@ class JourneyItemServiceTest { Document doc = makeDoc(docId, null, List.of(), null, null); JourneyItem item = savedItemWithDoc(itemId, journey, 10, doc, "Old note"); when(journeyItemRepository.findByIdAndGeschichteId(itemId, geschichteId)).thenReturn(Optional.of(item)); - when(documentService.getSummaryById(docId)).thenReturn(doc); JourneyItem saved = savedItemWithDoc(itemId, journey, 10, doc, null); when(journeyItemRepository.save(item)).thenReturn(saved); @@ -372,7 +371,6 @@ class JourneyItemServiceTest { Document doc = makeDoc(docId, null, List.of(), null, null); JourneyItem item = savedItemWithDoc(itemId, journey, 10, doc, "Old"); when(journeyItemRepository.findByIdAndGeschichteId(itemId, geschichteId)).thenReturn(Optional.of(item)); - when(documentService.getSummaryById(docId)).thenReturn(doc); JourneyItem saved = savedItemWithDoc(itemId, journey, 10, doc, null); when(journeyItemRepository.save(item)).thenReturn(saved);