Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
89122f6
Fix #27107: soft-deleted users still appear in experts/reviewers acro…
yan-3005 Apr 7, 2026
f56057c
Thread Include through bulk relationship resolution instead of hardco…
yan-3005 Apr 7, 2026
3264fb3
Fix inherited experts/owners including soft-deleted users from parent…
yan-3005 Apr 7, 2026
841775b
Fix soft-deleted users leaking into owners/experts/reviewers across a…
yan-3005 Apr 7, 2026
d4743a1
Fix test user email validation in soft-delete integration tests
yan-3005 Apr 7, 2026
05b41cb
Fix GlossaryTerm list test to filter by glossary ID
yan-3005 Apr 7, 2026
1a1888a
Fix fromId/toId swap in EntityRepository.batchFetchExperts
yan-3005 Apr 7, 2026
0c45006
Add merge function to Collectors.toMap in batchFetchExperts
yan-3005 Apr 7, 2026
639c950
Handle soft-deleted parent in setInheritedFields for DataProduct and …
yan-3005 Apr 7, 2026
97f328a
Remove dead setFieldsInBulk(Include) overload and collapse Include fr…
yan-3005 Apr 7, 2026
d9aa379
Paginate domain list to find test domain regardless of total count
yan-3005 Apr 7, 2026
00e7896
Merge branch 'main' into ram/fix-27107-soft-deleted-users-in-relations
yan-3005 Apr 7, 2026
37a014a
Revert WorksheetRepository Include change — out of scope for #27107
yan-3005 Apr 7, 2026
47def38
Merge branch 'main' into ram/fix-27107-soft-deleted-users-in-relations
yan-3005 Apr 8, 2026
4af35c3
Address PR review: add limit to DataProduct list test; align TagRepos…
yan-3005 Apr 8, 2026
b3d7482
Revert TagRepository Include changes — out of scope for #27107
yan-3005 Apr 8, 2026
d5446b1
Remove unnecessary changes and compilation error
yan-3005 Apr 8, 2026
736b773
Thread Include parameter through bulk relationship resolution path
yan-3005 Apr 8, 2026
007976e
Fix subclass bypass: use ThreadLocal to carry Include through virtual…
yan-3005 Apr 8, 2026
21c8e64
Merge branch 'main' into ram/fix-27107-soft-deleted-users-in-relations
yan-3005 Apr 8, 2026
f4a875e
Merge branch 'main' into ram/fix-27107-soft-deleted-users-in-relations
yan-3005 Apr 8, 2026
5e77478
Merge branch 'main' into ram/fix-27107-soft-deleted-users-in-relations
yan-3005 Apr 9, 2026
8b443b1
Fix null Include in setFieldsInBulk — default to NON_DELETED
yan-3005 Apr 9, 2026
85911a3
Merge branch 'main' into ram/fix-27107-soft-deleted-users-in-relations
yan-3005 Apr 12, 2026
6807212
Merge remote-tracking branch 'origin/main' into ram/fix-27107-soft-de…
yan-3005 Apr 17, 2026
70a4b67
Fix #27107: fix inverted ternary root cause; harden bulk-list NON_DEL…
yan-3005 Apr 20, 2026
344bc44
Merge branch 'main' into ram/fix-27107-soft-deleted-users-in-relations
yan-3005 Apr 20, 2026
7217773
Fix Copilot review: null-guard in batchFetchFollowers, remove dead 3-…
yan-3005 Apr 20, 2026
135be1c
fix: bump list limit to 1000000 in follower/voter IT tests to handle …
yan-3005 Apr 20, 2026
607743b
fix: remove unused Include param from listInternal and serializeJsons
yan-3005 Apr 20, 2026
9e31dbc
Merge branch 'main' into ram/fix-27107-soft-deleted-users-in-relations
yan-3005 Apr 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.openmetadata.schema.api.domains.CreateDomain.DomainType;
import org.openmetadata.schema.api.domains.DataProductPortsView;
import org.openmetadata.schema.api.services.CreateDatabaseService;
import org.openmetadata.schema.api.teams.CreateUser;
import org.openmetadata.schema.entity.data.Dashboard;
import org.openmetadata.schema.entity.data.Table;
import org.openmetadata.schema.entity.data.Topic;
Expand All @@ -41,6 +42,7 @@
import org.openmetadata.schema.entity.services.DashboardService;
import org.openmetadata.schema.entity.services.DatabaseService;
import org.openmetadata.schema.entity.services.MessagingService;
import org.openmetadata.schema.entity.teams.User;
import org.openmetadata.schema.entity.type.Style;
import org.openmetadata.schema.services.connections.database.MysqlConnection;
import org.openmetadata.schema.services.connections.database.common.basicAuth;
Expand Down Expand Up @@ -2873,4 +2875,78 @@
ResultList<Map<String, Object>> outputPorts = getOutputPorts(dataProduct.getId(), 10, 0);
assertEquals(0, outputPorts.getPaging().getTotal());
}

@Test
void softDeletedExpert_notReturnedInSingleGet(TestNamespace ns) {
OpenMetadataClient client = SdkClients.adminClient();
Domain domain = getOrCreateDomain(ns);

String userName = ns.prefix("expert_user");
User expert =
client
.users()
.create(

Check failure on line 2888 in openmetadata-integration-tests/src/test/java/org/openmetadata/it/tests/DataProductResourceIT.java

View workflow job for this annotation

GitHub Actions / Test Report

DataProductResourceIT.softDeletedExpert_notReturnedInSingleGet(TestNamespace)

[query param email must be a well-formed email address]
Raw output
InvalidRequestException (400): [query param email must be a well-formed email address]
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleErrorResponse(OpenMetadataHttpClient.java:326)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleResponse(OpenMetadataHttpClient.java:272)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:69)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:55)
	at org.openmetadata.sdk.services.teams.UserService.create(UserService.java:26)
	at org.openmetadata.it.tests.DataProductResourceIT.softDeletedExpert_notReturnedInSingleGet(DataProductResourceIT.java:2888)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1351)
	at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:422)
	at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:651)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
new CreateUser()
.withName(userName)
.withEmail(userName.replaceAll("[^a-zA-Z0-9]", "") + "@test.openmetadata.org")
.withDescription("Expert user for soft-delete test"));

CreateDataProduct create =
new CreateDataProduct()
.withName(ns.prefix("dp_softdel_expert"))
.withDescription("DataProduct for soft-delete expert test")
.withDomains(List.of(domain.getFullyQualifiedName()))
.withExperts(List.of(expert.getFullyQualifiedName()));
DataProduct dp = createEntity(create);

client.users().delete(expert.getId().toString());

DataProduct byId = client.dataProducts().get(dp.getId().toString(), "experts");
assertTrue(
byId.getExperts() == null || byId.getExperts().isEmpty(),
"Soft-deleted expert must not appear in single GET by ID");

DataProduct byName = client.dataProducts().getByName(dp.getFullyQualifiedName(), "experts");
assertTrue(
byName.getExperts() == null || byName.getExperts().isEmpty(),
"Soft-deleted expert must not appear in single GET by name");
}

@Test
void softDeletedExpert_notReturnedInListEndpoint(TestNamespace ns) {
OpenMetadataClient client = SdkClients.adminClient();
Domain domain = getOrCreateDomain(ns);

String userName = ns.prefix("expert_list_user");
User expert =
client
.users()
.create(

Check failure on line 2924 in openmetadata-integration-tests/src/test/java/org/openmetadata/it/tests/DataProductResourceIT.java

View workflow job for this annotation

GitHub Actions / Test Report

DataProductResourceIT.softDeletedExpert_notReturnedInListEndpoint(TestNamespace)

[query param email must be a well-formed email address, query param email size must be between 6 and 127]
Raw output
InvalidRequestException (400): [query param email must be a well-formed email address, query param email size must be between 6 and 127]
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleErrorResponse(OpenMetadataHttpClient.java:326)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleResponse(OpenMetadataHttpClient.java:272)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:69)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:55)
	at org.openmetadata.sdk.services.teams.UserService.create(UserService.java:26)
	at org.openmetadata.it.tests.DataProductResourceIT.softDeletedExpert_notReturnedInListEndpoint(DataProductResourceIT.java:2924)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1351)
	at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:422)
	at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:651)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
new CreateUser()
.withName(userName)
.withEmail(userName.replaceAll("[^a-zA-Z0-9]", "") + "@test.openmetadata.org")
.withDescription("Expert user for bulk soft-delete test"));

CreateDataProduct create =
new CreateDataProduct()
.withName(ns.prefix("dp_softdel_expert_list"))
.withDescription("DataProduct for soft-delete expert list test")
.withDomains(List.of(domain.getFullyQualifiedName()))
.withExperts(List.of(expert.getFullyQualifiedName()));
DataProduct dp = createEntity(create);

client.users().delete(expert.getId().toString());

ListParams params =
new ListParams().setFields("experts").withDomain(domain.getFullyQualifiedName());
Comment thread
yan-3005 marked this conversation as resolved.
Outdated
ListResponse<DataProduct> list = client.dataProducts().list(params);
DataProduct listed =
list.getData().stream()
.filter(p -> p.getId().equals(dp.getId()))
.findFirst()
.orElseThrow(() -> new AssertionError("DataProduct not found in list"));
assertTrue(
listed.getExperts() == null || listed.getExperts().isEmpty(),
"Soft-deleted expert must not appear in list endpoint");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
import org.openmetadata.it.util.TestNamespace;
import org.openmetadata.schema.api.domains.CreateDomain;
import org.openmetadata.schema.api.domains.CreateDomain.DomainType;
import org.openmetadata.schema.api.teams.CreateUser;
import org.openmetadata.schema.entity.domains.Domain;
import org.openmetadata.schema.entity.teams.User;
import org.openmetadata.schema.type.EntityHistory;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.sdk.client.OpenMetadataClient;
Expand Down Expand Up @@ -1153,4 +1155,75 @@
// Verify old child FQN no longer works
assertThrows(Exception.class, () -> getEntityByName(oldChildFqn));
}

@Test
void softDeletedExpert_notReturnedInSingleGet(TestNamespace ns) {
OpenMetadataClient client = SdkClients.adminClient();

String userName = ns.prefix("domain_expert");
User expert =
client
.users()
.create(

Check failure on line 1167 in openmetadata-integration-tests/src/test/java/org/openmetadata/it/tests/DomainResourceIT.java

View workflow job for this annotation

GitHub Actions / Test Report

DomainResourceIT.softDeletedExpert_notReturnedInSingleGet(TestNamespace)

[query param email must be a well-formed email address]
Raw output
InvalidRequestException (400): [query param email must be a well-formed email address]
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleErrorResponse(OpenMetadataHttpClient.java:326)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleResponse(OpenMetadataHttpClient.java:272)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:69)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:55)
	at org.openmetadata.sdk.services.teams.UserService.create(UserService.java:26)
	at org.openmetadata.it.tests.DomainResourceIT.softDeletedExpert_notReturnedInSingleGet(DomainResourceIT.java:1167)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1351)
	at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:422)
	at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:651)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
new CreateUser()
.withName(userName)
.withEmail(userName.replaceAll("[^a-zA-Z0-9]", "") + "@test.openmetadata.org")
.withDescription("Expert user for domain soft-delete test"));

CreateDomain create =
new CreateDomain()
.withName(ns.prefix("domain_softdel"))
.withDomainType(DomainType.AGGREGATE)
.withExperts(List.of(expert.getFullyQualifiedName()))
.withDescription("Domain for soft-delete expert test");
Domain domain = createEntity(create);

client.users().delete(expert.getId().toString());

Domain byId = client.domains().get(domain.getId().toString(), "experts");
assertTrue(
byId.getExperts() == null || byId.getExperts().isEmpty(),
"Soft-deleted expert must not appear in single GET by ID");

Domain byName = client.domains().getByName(domain.getFullyQualifiedName(), "experts");
assertTrue(
byName.getExperts() == null || byName.getExperts().isEmpty(),
"Soft-deleted expert must not appear in single GET by name");
}

@Test
void softDeletedExpert_notReturnedInListEndpoint(TestNamespace ns) {
OpenMetadataClient client = SdkClients.adminClient();

String userName = ns.prefix("domain_expert_list");
User expert =
client
.users()
.create(

Check failure on line 1202 in openmetadata-integration-tests/src/test/java/org/openmetadata/it/tests/DomainResourceIT.java

View workflow job for this annotation

GitHub Actions / Test Report

DomainResourceIT.softDeletedExpert_notReturnedInListEndpoint(TestNamespace)

[query param email size must be between 6 and 127, query param email must be a well-formed email address]
Raw output
InvalidRequestException (400): [query param email size must be between 6 and 127, query param email must be a well-formed email address]
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleErrorResponse(OpenMetadataHttpClient.java:326)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleResponse(OpenMetadataHttpClient.java:272)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:69)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:55)
	at org.openmetadata.sdk.services.teams.UserService.create(UserService.java:26)
	at org.openmetadata.it.tests.DomainResourceIT.softDeletedExpert_notReturnedInListEndpoint(DomainResourceIT.java:1202)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1351)
	at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:422)
	at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:651)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
new CreateUser()
.withName(userName)
.withEmail(userName.replaceAll("[^a-zA-Z0-9]", "") + "@test.openmetadata.org")
.withDescription("Expert user for domain list soft-delete test"));

CreateDomain create =
new CreateDomain()
.withName(ns.prefix("domain_softdel_list"))
.withDomainType(DomainType.AGGREGATE)
.withExperts(List.of(expert.getFullyQualifiedName()))
.withDescription("Domain for soft-delete expert list test");
Domain domain = createEntity(create);

client.users().delete(expert.getId().toString());

ListParams params = new ListParams().setFields("experts").withLimit(100);
ListResponse<Domain> list = listEntities(params);
Comment on lines +1313 to +1314
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test uses withLimit(1000000) to ensure the target domain appears in the list. This can make the test slower/flakier as the suite grows and can stress the list endpoint unnecessarily. Prefer paging (like the earlier experts tests in this file) or a smaller limit combined with cursor iteration.

Copilot uses AI. Check for mistakes.
Domain listed =
list.getData().stream()
.filter(d -> d.getId().equals(domain.getId()))
.findFirst()
.orElseThrow(() -> new AssertionError("Domain not found in list"));
assertTrue(
listed.getExperts() == null || listed.getExperts().isEmpty(),
"Soft-deleted expert must not appear in list endpoint");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.openmetadata.schema.api.data.CreateTable;
import org.openmetadata.schema.api.data.TermReference;
import org.openmetadata.schema.api.feed.CreateThread;
import org.openmetadata.schema.api.teams.CreateUser;
import org.openmetadata.schema.entity.data.DatabaseSchema;
import org.openmetadata.schema.entity.data.Glossary;
import org.openmetadata.schema.entity.data.GlossaryTerm;
Expand Down Expand Up @@ -3147,4 +3148,41 @@
null,
optionsBuilder.build());
}

@Test
void softDeletedReviewer_notReturnedInListEndpoint(TestNamespace ns) {
OpenMetadataClient client = SdkClients.adminClient();
Glossary glossary = getOrCreateGlossary(ns);

String userName = ns.prefix("reviewer_list");
User reviewer =
client
.users()
.create(

Check failure on line 3161 in openmetadata-integration-tests/src/test/java/org/openmetadata/it/tests/GlossaryTermResourceIT.java

View workflow job for this annotation

GitHub Actions / Test Report

GlossaryTermResourceIT.softDeletedReviewer_notReturnedInListEndpoint(TestNamespace)

[query param email must be a well-formed email address, query param email size must be between 6 and 127]
Raw output
InvalidRequestException (400): [query param email must be a well-formed email address, query param email size must be between 6 and 127]
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleErrorResponse(OpenMetadataHttpClient.java:326)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.handleResponse(OpenMetadataHttpClient.java:272)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:69)
	at org.openmetadata.sdk.network.OpenMetadataHttpClient.execute(OpenMetadataHttpClient.java:55)
	at org.openmetadata.sdk.services.teams.UserService.create(UserService.java:26)
	at org.openmetadata.it.tests.GlossaryTermResourceIT.softDeletedReviewer_notReturnedInListEndpoint(GlossaryTermResourceIT.java:3161)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1351)
	at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:422)
	at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:651)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.tryRemoveAndExec(ForkJoinPool.java:1351)
	at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:422)
	at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:651)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
new CreateUser()
.withName(userName)
.withEmail(userName.replaceAll("[^a-zA-Z0-9]", "") + "@test.openmetadata.org")
.withDescription("Reviewer user for glossary soft-delete list test"));

CreateGlossaryTerm create =
new CreateGlossaryTerm()
.withName(ns.prefix("term_softdel_reviewer"))
.withGlossary(glossary.getFullyQualifiedName())
.withDescription("Term for soft-delete reviewer list test")
.withReviewers(List.of(reviewer.getEntityReference()));
GlossaryTerm term = createEntity(create);

client.users().delete(reviewer.getId().toString());

ListParams params = new ListParams().setFields("reviewers").withLimit(100);
ListResponse<GlossaryTerm> list = listEntities(params);
GlossaryTerm listed =
list.getData().stream()
.filter(t -> t.getId().equals(term.getId()))
.findFirst()
.orElseThrow(() -> new AssertionError("GlossaryTerm not found in list"));
assertTrue(
listed.getReviewers() == null || listed.getReviewers().isEmpty(),
"Soft-deleted reviewer must not appear in list endpoint");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.jdbi.v3.sqlobject.transaction.Transaction;
Expand Down Expand Up @@ -967,24 +968,30 @@ private Map<UUID, List<EntityReference>> batchFetchExperts(List<DataProduct> dat
return expertsMap;
}

// Initialize empty lists for all data products
for (DataProduct dataProduct : dataProducts) {
expertsMap.put(dataProduct.getId(), new ArrayList<>());
}

// Single batch query to get all expert relationships
List<CollectionDAO.EntityRelationshipObject> records =
daoCollection
.relationshipDAO()
.findToBatch(
entityListToStrings(dataProducts), Relationship.EXPERT.ordinal(), Entity.USER);

// Group experts by data product ID
List<UUID> expertIds =
records.stream().map(r -> UUID.fromString(r.getToId())).distinct().toList();
Map<UUID, EntityReference> expertRefsById =
Entity.getEntityReferencesByIdsRespectingInclude(
Entity.USER, expertIds, Include.NON_DELETED)
.stream()
.collect(Collectors.toMap(EntityReference::getId, Function.identity()));
Comment thread
gitar-bot[bot] marked this conversation as resolved.
Outdated

for (CollectionDAO.EntityRelationshipObject record : records) {
UUID dataProductId = UUID.fromString(record.getFromId());
EntityReference expertRef =
Entity.getEntityReferenceById(
Entity.USER, UUID.fromString(record.getToId()), NON_DELETED);
EntityReference expertRef = expertRefsById.get(UUID.fromString(record.getToId()));
if (expertRef == null) {
continue;
}
expertsMap.get(dataProductId).add(expertRef);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.jdbi.v3.sqlobject.transaction.Transaction;
Expand Down Expand Up @@ -580,22 +581,28 @@ private Map<UUID, List<EntityReference>> batchFetchExperts(List<Domain> domains)
return expertsMap;
}

// Initialize empty lists for all domains
domains.forEach(domain -> expertsMap.put(domain.getId(), new ArrayList<>()));

// Single batch query to get all expert relationships
var records =
daoCollection
.relationshipDAO()
.findToBatch(entityListToStrings(domains), Relationship.EXPERT.ordinal(), Entity.USER);

// Group experts by domain ID
List<UUID> expertIds =
records.stream().map(r -> UUID.fromString(r.getToId())).distinct().toList();
Map<UUID, EntityReference> expertRefsById =
Entity.getEntityReferencesByIdsRespectingInclude(
Entity.USER, expertIds, Include.NON_DELETED)
.stream()
.collect(Collectors.toMap(EntityReference::getId, Function.identity()));

records.forEach(
record -> {
var domainId = UUID.fromString(record.getFromId());
var expertRef =
getEntityReferenceById(Entity.USER, UUID.fromString(record.getToId()), NON_DELETED);
expertsMap.get(domainId).add(expertRef);
var expertRef = expertRefsById.get(UUID.fromString(record.getToId()));
if (expertRef != null) {
expertsMap.get(domainId).add(expertRef);
}
});

return expertsMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8704,7 +8704,8 @@ private Map<String, Map<UUID, EntityReference>> resolveRelationshipEntityReferen
Map<String, Map<UUID, EntityReference>> refsByType = new HashMap<>();
for (Entry<String, Set<UUID>> entry : idsByType.entrySet()) {
List<EntityReference> refs =
Entity.getEntityReferencesByIds(entry.getKey(), new ArrayList<>(entry.getValue()), ALL);
Entity.getEntityReferencesByIdsRespectingInclude(
entry.getKey(), new ArrayList<>(entry.getValue()), Include.NON_DELETED);
Comment thread
gitar-bot[bot] marked this conversation as resolved.
Outdated
refsByType.put(
entry.getKey(),
refs.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,8 @@ public T getInternal(
String includeRelations) {
Fields fields = getFields(fieldsParam);
OperationContext operationContext = new OperationContext(entityType, getViewOperations(fields));
RelationIncludes relationIncludes = new RelationIncludes(include, includeRelations);
Include resolvedInclude = include != null ? include : Include.NON_DELETED;
RelationIncludes relationIncludes = new RelationIncludes(resolvedInclude, includeRelations);
return getInternal(
uriInfo,
securityContext,
Expand Down Expand Up @@ -388,7 +389,8 @@ public T getByNameInternal(
String includeRelations) {
Fields fields = getFields(fieldsParam);
OperationContext operationContext = new OperationContext(entityType, getViewOperations(fields));
RelationIncludes relationIncludes = new RelationIncludes(include, includeRelations);
Include resolvedInclude = include != null ? include : Include.NON_DELETED;
RelationIncludes relationIncludes = new RelationIncludes(resolvedInclude, includeRelations);
return getByNameInternal(
uriInfo,
securityContext,
Expand Down
Loading