From 1247b51d9ef13dd989ca64b313f21e76657f4535 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 19 May 2026 08:44:53 +0200 Subject: [PATCH] chore(document): address non-blocking review feedback on lazy-fetch PR - Add @BatchSize(50) fallback comments on findBySenderId / findByReceiversId - Replace silent size() discard in getRecentActivity test with assertThat isNotEmpty() - Add ADR-022 reference comment above @JsonIgnoreProperties on Person and Tag - Document within-open-transaction limitation in DocumentLazyLoadingTest Javadoc Co-Authored-By: Claude Sonnet 4.6 --- .../familienarchiv/document/DocumentRepository.java | 2 ++ .../org/raddatz/familienarchiv/person/Person.java | 1 + .../java/org/raddatz/familienarchiv/tag/Tag.java | 1 + .../document/DocumentLazyLoadingTest.java | 12 ++++++++++++ 4 files changed, 16 insertions(+) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/document/DocumentRepository.java b/backend/src/main/java/org/raddatz/familienarchiv/document/DocumentRepository.java index e887eeb8..c28a8132 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/document/DocumentRepository.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/document/DocumentRepository.java @@ -50,9 +50,11 @@ public interface DocumentRepository extends JpaRepository, JpaSp // Prüft effizient, ob ein Dateiname schon existiert (gibt true/false zurück) boolean existsByOriginalFilename(String originalFilename); + // lazy – @BatchSize(50) fallback active; see ADR-022 @EntityGraph("Document.full") List findBySenderId(UUID senderId); + // lazy – @BatchSize(50) fallback active; see ADR-022 @EntityGraph("Document.full") List findByReceiversId(UUID receiverId); diff --git a/backend/src/main/java/org/raddatz/familienarchiv/person/Person.java b/backend/src/main/java/org/raddatz/familienarchiv/person/Person.java index c99a6f76..d2332519 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/person/Person.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/person/Person.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +// prevents infinite recursion in JSON serialization; see ADR-022 for lazy-fetch context @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) @Entity @Table(name = "persons") diff --git a/backend/src/main/java/org/raddatz/familienarchiv/tag/Tag.java b/backend/src/main/java/org/raddatz/familienarchiv/tag/Tag.java index 8be07fdc..fc5974a6 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/tag/Tag.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/tag/Tag.java @@ -7,6 +7,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.persistence.*; import lombok.*; +// prevents infinite recursion in JSON serialization; see ADR-022 for lazy-fetch context @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) @Entity @Data diff --git a/backend/src/test/java/org/raddatz/familienarchiv/document/DocumentLazyLoadingTest.java b/backend/src/test/java/org/raddatz/familienarchiv/document/DocumentLazyLoadingTest.java index 3db5caaa..bc33815f 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/document/DocumentLazyLoadingTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/document/DocumentLazyLoadingTest.java @@ -28,6 +28,17 @@ import static org.assertj.core.api.Assertions.assertThatCode; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; +/** + * Verifies that lazy-loaded associations on {@link Document} are accessible after a service + * method returns — i.e. no {@link org.hibernate.LazyInitializationException} is thrown outside + * the Hibernate session that loaded the entity. + * + *

Known limitation: calling {@code getDocumentById} (or any other service method) from + * within an already-open transaction is not covered here. When an outer transaction is active, + * the service's own {@code @Transactional} merges into it and Hibernate keeps the same session + * open, so the lazy-init guard behaves differently than in a non-transactional caller. This is a + * known constraint of the test setup, not a bug in the production code. + */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) @ActiveProfiles("test") @Import(PostgresContainerConfig.class) @@ -100,6 +111,7 @@ class DocumentLazyLoadingTest { }).doesNotThrowAnyException(); results.forEach(d -> assertThat(d.getSender()).isNotNull()); results.forEach(d -> assertThat(d.getSender().getLastName()).isNotNull()); + results.forEach(d -> assertThat(d.getTags()).isNotEmpty()); } @Test