Skip to content

Commit

Permalink
fix(change-ownership) fix "Invalid reference" appears after updating … (
Browse files Browse the repository at this point in the history
  • Loading branch information
SvitlanaKovalova1 authored Dec 17, 2024
1 parent b7dc56f commit b7bb1a3
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 3 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* Fix old browse config returned on get after upsert ([MSEARCH-897](https://folio-org.atlassian.net/browse/MSEARCH-897))
* Fix generation of IDs ranges in Reindex Upload for Subject, Classification and Contributor ([MSEARCH-907](https://folio-org.atlassian.net/browse/MSEARCH-907))
* Remove browse config caching ([MSEARCH-897](https://folio-org.atlassian.net/browse/MSEARCH-897))
* Fix the "Invalid reference" appears after updating ownership ([MSEARCH-915](https://folio-org.atlassian.net/browse/MSEARCH-915))

### Tech Dept
* Description ([ISSUE](https://folio-org.atlassian.net/browse/ISSUE))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,8 @@ private void process(String tenant, List<ResourceEvent> batch) {
.map(ResourceEvent::getId)
.toList();
if (!idsToDrop.isEmpty()) {
repository.deleteEntities(idsToDrop);
deleteEntities(tenant, recordCollection.getKey(), repository, idsToDrop);
}

if (ResourceType.INSTANCE.getName().equals(recordCollection.getKey())) {
var noShadowCopiesInstanceEvents = recordByOperation.values().stream().flatMap(Collection::stream).toList();
instanceChildrenResourceService.persistChildren(tenant, noShadowCopiesInstanceEvents);
Expand All @@ -128,6 +127,14 @@ private void process(String tenant, List<ResourceEvent> batch) {
}
}

private void deleteEntities(String tenant, String resourceType, MergeRangeRepository repository, List<String> ids) {
if (ResourceType.HOLDINGS.getName().equals(resourceType) || ResourceType.ITEM.getName().equals(resourceType)) {
repository.deleteEntitiesForTenant(ids, tenant);
} else {
repository.deleteEntities(ids);
}
}

private boolean isInstanceEvent(ResourceEvent event) {
var resourceName = event.getResourceName();
return ResourceType.INSTANCE.getName().equals(resourceName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import static org.folio.search.service.reindex.ReindexConstants.MERGE_RANGE_TABLE;
import static org.folio.search.utils.JdbcUtils.getFullTableName;
import static org.folio.search.utils.JdbcUtils.getParamPlaceholderForUuid;
import static org.folio.search.utils.JdbcUtils.getParamPlaceholderForUuidArray;

import jakarta.persistence.GenerationType;
import java.util.List;
import java.util.Map;
import java.util.UUID;
Expand All @@ -18,9 +20,13 @@

public abstract class MergeRangeRepository extends ReindexJdbcRepository {

protected static final String DELETE_SQL = """
private static final String DELETE_SQL = """
DELETE FROM %s WHERE id IN (%s);
""";

private static final String DELETE_SQL_FOR_TENANT = """
DELETE FROM %s WHERE id = ANY (%s) AND tenant_id = ?;
""";
private static final String INSERT_MERGE_RANGE_SQL = """
INSERT INTO %s (id, entity_type, tenant_id, lower, upper, created_at, finished_at)
VALUES (?, ?, ?, ?, ?, ?, ?);
Expand Down Expand Up @@ -66,6 +72,17 @@ protected String rangeTable() {

public abstract void saveEntities(String tenantId, List<Map<String, Object>> entities);

public void deleteEntitiesForTenant(List<String> ids, String tenantId) {
var fullTableName = getFullTableName(context, entityTable());
var paramPlaceholder = getParamPlaceholderForUuidArray(ids.size(), GenerationType.UUID.name());
var sql = DELETE_SQL_FOR_TENANT.formatted(fullTableName, paramPlaceholder);

jdbcTemplate.update(sql, statement -> {
statement.setArray(1, statement.getConnection().createArrayOf(GenerationType.UUID.name(), ids.toArray()));
statement.setString(2, tenantId);
});
}

public void deleteEntities(List<String> ids) {
var fullTableName = getFullTableName(context, entityTable());
var sql = DELETE_SQL.formatted(fullTableName, getParamPlaceholderForUuid(ids.size()));
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/folio/search/utils/JdbcUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ public static String getParamPlaceholderForUuid(int size) {
return getParamPlaceholder(size, "uuid");
}

public static String getParamPlaceholderForUuidArray(int size, String cast) {
return String.join(",", nCopies(size, "?" + (cast == null ? "" : "::" + cast + "[]")));
}

public static String getParamPlaceholder(int size) {
return getParamPlaceholder(size, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.folio.search.utils.TestConstants.MEMBER_TENANT_ID;
import static org.folio.search.utils.TestConstants.TENANT_ID;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -179,6 +180,48 @@ void saveEntities() {
.contains(mainInstanceId.toString(), holdingId1.toString(), holdingId2.toString());
}

@Test
@SuppressWarnings("unchecked")
void deleteEntities() {
// given
var instanceId = UUID.randomUUID();
var holdingId1 = UUID.randomUUID();
var holdingId2 = UUID.randomUUID();
var itemId1 = UUID.randomUUID();
var itemId2 = UUID.randomUUID();

var instances = List.of(Map.<String, Object>of("id", instanceId));
var holdings = List.of(
Map.<String, Object>of("id", holdingId1, "instanceId", instanceId),
Map.<String, Object>of("id", holdingId2, "instanceId", instanceId));
var items = List.of(
Map.<String, Object>of("id", itemId1, "instanceId", instanceId, "holdingsRecordId", holdingId1),
Map.<String, Object>of("id", itemId2, "instanceId", instanceId, "holdingsRecordId", holdingId2));

// act
instanceRepository.saveEntities(TENANT_ID, instances);
holdingRepository.saveEntities(TENANT_ID, holdings);
itemRepository.saveEntities(TENANT_ID, items);

//save the same entities for the "member_tenant" tenant
holdingRepository.saveEntities(MEMBER_TENANT_ID, holdings);
itemRepository.saveEntities(MEMBER_TENANT_ID, items);

// assert
assertThat(instanceRepository.countEntities()).isEqualTo(1);
assertThat(List.of(holdingRepository.countEntities(), itemRepository.countEntities()))
.allMatch(count -> count == 4);

//act
holdingRepository.deleteEntitiesForTenant(List.of(holdingId1.toString()), TENANT_ID);
itemRepository.deleteEntitiesForTenant(List.of(itemId1.toString()), TENANT_ID);

// assert
assertThat(instanceRepository.countEntities()).isEqualTo(1);
assertThat(List.of(holdingRepository.countEntities(), itemRepository.countEntities()))
.allMatch(count -> count == 3);
}

private List<String> extractMapValues(List<Map<String, Object>> maps) {
return maps.stream().map(Map::values).flatMap(Collection::stream).map(String::valueOf).toList();
}
Expand Down

0 comments on commit b7bb1a3

Please sign in to comment.