RED-8811: Merge in recreated type does not work properly

This commit is contained in:
Maverick Studer 2024-11-21 16:06:38 +01:00
parent f08a2d512a
commit b62a9b9ae6
5 changed files with 118 additions and 11 deletions

View File

@ -239,10 +239,11 @@ public class DictionaryManagementService {
@Transactional
public void addEntries(String typeId, List<String> entries, boolean removeCurrent, boolean ignoreInvalidEntries, DictionaryEntryType dictionaryEntryType) {
addEntries(typeId, entries, removeCurrent, ignoreInvalidEntries, dictionaryEntryType, false);
}
@Transactional
public void addEntries(String typeId, List<String> entries, boolean removeCurrent, boolean ignoreInvalidEntries, DictionaryEntryType dictionaryEntryType, boolean isImport) {
@ -293,7 +294,10 @@ public class DictionaryManagementService {
// check for the existence of dossier type and create in case it does not exist
if (isDossierTypeId(typeId)) {
try {
dictionaryPersistenceService.getType(typeId);
TypeEntity type = dictionaryPersistenceService.getType(typeId, true);
if (type.isDeleted()) {
dictionaryPersistenceService.undeleteType(typeId);
}
} catch (NotFoundException e) {
// type not found check first dossier is matching the specified dossier template
var dossierId = getDossierIdFromTypeId(typeId);
@ -397,9 +401,13 @@ public class DictionaryManagementService {
dictionaryPersistenceService.deleteType(typeId);
entryPersistenceService.deleteAllEntriesForTypeId(typeId, currentVersion + 1, DictionaryEntryType.ENTRY);
entryPersistenceService.deleteAllEntriesForTypeId(typeId, currentVersion + 1, DictionaryEntryType.FALSE_POSITIVE);
entryPersistenceService.deleteAllEntriesForTypeId(typeId, currentVersion + 1, DictionaryEntryType.FALSE_RECOMMENDATION);
if (isDossierTypeId(typeId)) {
entryPersistenceService.hardDeleteAllEntriesForTypeId(typeId);
} else {
entryPersistenceService.deleteAllEntriesForTypeId(typeId, currentVersion + 1, DictionaryEntryType.ENTRY);
entryPersistenceService.deleteAllEntriesForTypeId(typeId, currentVersion + 1, DictionaryEntryType.FALSE_POSITIVE);
entryPersistenceService.deleteAllEntriesForTypeId(typeId, currentVersion + 1, DictionaryEntryType.FALSE_RECOMMENDATION);
}
dictionaryPersistenceService.incrementVersion(typeId);
}

View File

@ -184,6 +184,13 @@ public class EntryPersistenceService {
}
@Transactional
public void hardDeleteAllEntriesForTypeId(String typeId) {
entryRepository.hardDeleteAllEntriesForTypeId(typeId);
}
public void cloneEntries(String originalTypeId, String newTypeId) {
entryRepository.cloneEntries(originalTypeId, newTypeId);

View File

@ -86,7 +86,7 @@ public interface TypeRepository extends JpaRepository<TypeEntity, String> {
void softDeleteTypeById(@Param("typeId") String typeId);
@Modifying
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query("Update TypeEntity t set t.softDeletedTime = null where t.id = :typeId and t.softDeletedTime is not null")
int unSoftDeleteTypeById(@Param("typeId") String typeId);

View File

@ -29,6 +29,11 @@ public interface EntryRepository extends EntryRepositoryCustom, JpaRepository<Di
void deleteAllEntriesForTypeId(@Param("typeId") String typeId, @Param("version") long version);
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query("delete from DictionaryEntryEntity e where e.typeId = :typeId")
void hardDeleteAllEntriesForTypeId(@Param("typeId") String typeId);
@Modifying(flushAutomatically = true, clearAutomatically = true)
@Transactional
@Query(value = "insert into dictionary_entry (value, version, deleted, type_id) "

View File

@ -26,19 +26,20 @@ import com.iqser.red.service.peristence.v1.server.integration.service.DossierTem
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.service.TypeProvider;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DictionaryEntryEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.DictionaryManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.DictionaryService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.TypeRepository;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.EntryRepository;
import com.iqser.red.service.persistence.service.v1.api.external.model.UpdateEntries;
import com.iqser.red.service.persistence.service.v1.api.shared.model.CreateTypeValue;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeValue;
import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateTypeValue;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.Dictionary;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifference;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifferencePerType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifferenceResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType;
import com.knecon.fforesight.tenantcommons.TenantContext;
@ -67,6 +68,12 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
@Autowired
private DossierClient dossierClient;
@Autowired
private TypeRepository typeRepository;
@Autowired
private EntryRepository entryRepository;
private final List<String> testList1 = List.of("William c. Spare", "Charalampos", "Carina Wilson", "PATRICIA A. SHEEHY", "William C. Spare", "carlsen", "Patricia A. Sheehy");
private final List<String> testList2 = List.of("William C. Spare", "Charalampos", "Carina Wilson", "Patricia A. Sheehy", "William c. Spare", "carlsen", "PATRICIA A. SHEEHY");
@ -1176,7 +1183,7 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
var type = dictionaryClient.addType(createTypeValue);
List<TypeValue> customTypes = dictionaryClient.getAllTypes(dossierTemplate.getId(), dossier.getId(), false).getTypes()
List<TypeValue> customTypes = dictionaryClient.getAllTypes(dossierTemplate.getId(), dossier.getId(), false).getTypes()
.stream()
.filter(t -> !t.isSystemManaged())
.toList();
@ -1205,6 +1212,86 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
}
@Test
void testRecreateTypeAndCheckMergedDictionary() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate, "TestDossier");
var type = typeProvider.testAndProvideType(dossierTemplate, null, "type1", false);
List<String> templateEntries = List.of("aaa", "bbb");
dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), templateEntries, false, null, DictionaryEntryType.ENTRY);
var templateDictionary = dictionaryClient.getDictionaryForType(type.getType(), dossierTemplate.getId(), null);
assertThat(templateDictionary.getEntries()).containsExactlyInAnyOrderElementsOf(templateEntries);
List<String> dossierEntries = List.of("ccc");
dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), dossierEntries, false, dossier.getId(), DictionaryEntryType.ENTRY);
var dossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), dossierTemplate.getId(), dossier.getId());
assertThat(dossierDictionary.getEntries()).containsExactlyInAnyOrderElementsOf(dossierEntries);
Dictionary mergedDictionary = dictionaryClient.getMergedDictionaries(type.getType(), type.getDossierTemplateId(), dossier.getId());
assertThat(mergedDictionary).isNotNull();
List<String> allEntries = new ArrayList<>(templateEntries);
allEntries.addAll(dossierEntries);
assertThat(mergedDictionary.getEntries()).containsExactlyInAnyOrderElementsOf(allEntries);
List<String> newDossierEntries = List.of("entry d");
UpdateEntries updateEntries = new UpdateEntries(newDossierEntries, allEntries);
dictionaryClient.updateEntries(type.getType(), type.getDossierTemplateId(), updateEntries, dossier.getId(), DictionaryEntryType.ENTRY);
List<DictionaryEntryEntity> deleted = entryRepository.findAll().stream().filter(DictionaryEntryEntity::isDeleted).toList();
assertEquals(3, deleted.size());
var updatedDossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), dossierTemplate.getId(), dossier.getId());
assertThat(updatedDossierDictionary.getEntries()).containsExactlyInAnyOrderElementsOf(newDossierEntries);
// deletion
dictionaryClient.deleteType(type.getType(), type.getDossierTemplateId());
Assertions.assertThrows(FeignException.NotFound.class, () -> dictionaryClient.getDictionaryForType(type.getType(), dossierTemplate.getId(), null));
List<TypeEntity> deletedType1Entities = typeRepository.findAllTypesByDossierTemplateIdOrDossierId(dossierTemplate.getId(), dossier.getId())
.stream()
.filter(typeEntity -> typeEntity.getType().equals("type1") && typeEntity.isDeleted())
.toList();
assertEquals(2, deletedType1Entities.size());
deleted = entryRepository.findAll().stream().filter(DictionaryEntryEntity::isDeleted).toList();
assertEquals(2, deleted.size());
// recreation
var type2 = typeProvider.testAndProvideType(dossierTemplate, null, "type1", false);
dictionaryClient.addEntry(type2.getType(), type2.getDossierTemplateId(), templateEntries, false, null, DictionaryEntryType.ENTRY);
deleted = entryRepository.findAll().stream().filter(DictionaryEntryEntity::isDeleted).toList();
assertEquals(0, deleted.size());
deletedType1Entities = typeRepository.findAllTypesByDossierTemplateIdOrDossierId(dossierTemplate.getId(), dossier.getId())
.stream()
.filter(typeEntity -> typeEntity.getType().equals("type1") && typeEntity.isDeleted())
.toList();
assertEquals(1, deletedType1Entities.size());
// problematic call because it creates/update entities on a get
dictionaryClient.getAllTypes(dossierTemplate.getId(), dossier.getId(), false);
deletedType1Entities = typeRepository.findAllTypesByDossierTemplateIdOrDossierId(dossierTemplate.getId(), dossier.getId())
.stream()
.filter(typeEntity -> typeEntity.getType().equals("type1") && typeEntity.isDeleted())
.toList();
assertEquals(0, deletedType1Entities.size());
Dictionary mergedDictionary2 = dictionaryClient.getMergedDictionaries(type2.getType(), type2.getDossierTemplateId(), dossier.getId());
assertThat(mergedDictionary2).isNotNull();
assertThat(mergedDictionary2.getEntries()).containsExactlyInAnyOrderElementsOf(templateEntries);
assertThat(mergedDictionary2.getEntries()).doesNotContain("entry d");
}
private static final class ListContentWithoutOrderAndWithoutDuplicatesComparator<T> implements Comparator<List<? extends T>> {
@SuppressWarnings("SuspiciousMethodCalls")