Compare commits
6 Commits
e13b37d585
...
3358f0509f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3358f0509f | ||
|
|
667b237c33 | ||
|
|
e677756139 | ||
|
|
108ab1a288 | ||
|
|
5f83fa1bc2 | ||
|
|
0dd7d8a5e7 |
@@ -136,6 +136,7 @@ public class Document {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "sender_id")
|
||||
@BatchSize(size = 50)
|
||||
private Person sender;
|
||||
|
||||
@ManyToMany(fetch = FetchType.LAZY)
|
||||
@@ -148,6 +149,7 @@ public class Document {
|
||||
@CollectionTable(name = "document_training_labels", joinColumns = @JoinColumn(name = "document_id"))
|
||||
@Column(name = "label")
|
||||
@Enumerated(EnumType.STRING)
|
||||
@BatchSize(size = 50)
|
||||
@Builder.Default
|
||||
private Set<TrainingLabel> trainingLabels = new HashSet<>();
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ public interface DocumentRepository extends JpaRepository<Document, UUID>, JpaSp
|
||||
@EntityGraph("Document.list")
|
||||
List<Document> findAll(Specification<Document> spec);
|
||||
|
||||
@EntityGraph("Document.list")
|
||||
Page<Document> findAll(Pageable pageable);
|
||||
|
||||
// Findet ein Dokument anhand des ursprünglichen Dateinamens
|
||||
// Wichtig für den Abgleich beim Excel-Import & Datei-Upload
|
||||
|
||||
@@ -636,7 +636,8 @@ public class DocumentService {
|
||||
return saved;
|
||||
}
|
||||
|
||||
// 0. Zuletzt aktive Dokumente (sortiert nach updatedAt DESC)
|
||||
// @Transactional(readOnly=true) keeps the Hibernate session open so the
|
||||
// lazy-loaded sender and tags on returned documents remain accessible to callers.
|
||||
@Transactional(readOnly = true)
|
||||
public List<Document> getRecentActivity(int size) {
|
||||
return documentRepository.findAll(
|
||||
@@ -845,6 +846,8 @@ public class DocumentService {
|
||||
documentRepository.save(doc);
|
||||
}
|
||||
|
||||
// @Transactional(readOnly=true) keeps the Hibernate session open so the
|
||||
// lazy-loaded tags and receivers on the returned document remain accessible to callers.
|
||||
@Transactional(readOnly = true)
|
||||
public Document getDocumentById(UUID id) {
|
||||
Document doc = documentRepository.findById(id)
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -84,7 +85,7 @@ class DocumentLazyLoadingTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getRecentActivity_doesNotThrowLazyInitializationException() {
|
||||
void getRecentActivity_collectionsAccessibleAfterReturn() {
|
||||
Person sender = personRepository.save(Person.builder().firstName("Hans").lastName("RaSender").build());
|
||||
Tag tag = tagRepository.save(Tag.builder().name("RaTag").build());
|
||||
for (int i = 0; i < 3; i++) {
|
||||
@@ -96,8 +97,13 @@ class DocumentLazyLoadingTest {
|
||||
.build());
|
||||
}
|
||||
|
||||
assertThatCode(() -> documentService.getRecentActivity(3))
|
||||
.doesNotThrowAnyException();
|
||||
List<Document> results = documentService.getRecentActivity(3);
|
||||
|
||||
assertThatCode(() -> {
|
||||
results.forEach(d -> assertThat(d.getSender()).isNotNull());
|
||||
results.forEach(d -> assertThat(d.getSender().getLastName()).isNotNull());
|
||||
results.forEach(d -> d.getTags().size());
|
||||
}).doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -560,6 +560,31 @@ class DocumentRepositoryTest {
|
||||
.isLessThanOrEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAll_withPageable_loadsSenderWithoutNPlusOne() {
|
||||
Person sender = personRepository.save(Person.builder().firstName("Maria").lastName("RaSender").build());
|
||||
Tag tag = tagRepository.save(Tag.builder().name("RaTag2").build());
|
||||
for (int i = 0; i < 5; i++) {
|
||||
documentRepository.save(Document.builder()
|
||||
.title("RaDoc2 " + i).originalFilename("radoc2_" + i + ".pdf")
|
||||
.status(DocumentStatus.UPLOADED)
|
||||
.sender(sender)
|
||||
.tags(new HashSet<>(Set.of(tag)))
|
||||
.build());
|
||||
}
|
||||
entityManager.flush();
|
||||
entityManager.clear();
|
||||
Statistics stats = entityManagerFactory.unwrap(SessionFactory.class).getStatistics();
|
||||
stats.setStatisticsEnabled(true);
|
||||
stats.clear();
|
||||
|
||||
documentRepository.findAll(PageRequest.of(0, 5, Sort.by(Sort.Direction.DESC, "updatedAt")));
|
||||
|
||||
assertThat(stats.getPrepareStatementCount())
|
||||
.as("@EntityGraph(Document.list) via findAll(Pageable) must not N+1 sender for 5 docs")
|
||||
.isLessThanOrEqualTo(5);
|
||||
}
|
||||
|
||||
// ─── seeding helpers ─────────────────────────────────────────────────────
|
||||
|
||||
private Document uploaded(String title) {
|
||||
|
||||
@@ -13,10 +13,6 @@ spring:
|
||||
password: test
|
||||
mail:
|
||||
host: localhost
|
||||
jpa:
|
||||
properties:
|
||||
hibernate:
|
||||
generate_statistics: true
|
||||
|
||||
# Disable OTel SDK entirely in tests — prevents auto-configuration from loading resource providers
|
||||
# (e.g. AzureAppServiceResourceProvider) that fail against the semconv version used here.
|
||||
|
||||
Reference in New Issue
Block a user