RED-7049 - Wrong error code when adding entity with already existing rank - backport

- correct the query to get the type with same rank.
- changed to get the list of types instead of a one result for the case with several types with the same rank
- added junit tests

Signed-off-by: Corina Olariu <corina.olariu.ext@knecon.com>
This commit is contained in:
Corina Olariu 2024-03-04 15:40:16 +02:00
parent 68707c3fa7
commit ddfc156f13
4 changed files with 108 additions and 38 deletions

View File

@ -12,6 +12,7 @@ import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository;
@ -85,18 +86,20 @@ public class DictionaryPersistenceService {
private void checkRankAlreadyExists(String type, String dossierTemplateId, int rank, String dossierId) { private void checkRankAlreadyExists(String type, String dossierTemplateId, int rank, String dossierId) {
Optional<TypeEntity> existingTypeValueForRank = getTypeForRank(dossierTemplateId, rank, dossierId); List<TypeEntity> existingTypesForRank = getTypesForRank(dossierTemplateId, rank, dossierId);
if (!existingTypesForRank.isEmpty()) {
if (existingTypeValueForRank.isPresent() && !existingTypeValueForRank.get().isDeleted() && !existingTypeValueForRank.get().getType().equalsIgnoreCase(type)) { for (var existingTypeValueForRank : existingTypesForRank) {
throw new BadRequestException("Rank already exists: " + rank + " on type: " + existingTypeValueForRank.get().getType()); if (!existingTypeValueForRank.isDeleted() && !existingTypeValueForRank.getType().equalsIgnoreCase(type)) {
throw new ConflictException("Rank already exists: " + rank + " on type: " + existingTypeValueForRank.getType());
}
}
} }
} }
private Optional<TypeEntity> getTypeForRank(String dossierTemplateId, int rank, String dossierId) { private List<TypeEntity> getTypesForRank(String dossierTemplateId, int rank, String dossierId) {
return typeRepository.findOneByDossierTemplateIdAndDossierIdAndRank(dossierTemplateId, dossierId, rank); return typeRepository.findByDossierTemplateIdAndDossierIdAndRank(dossierTemplateId, dossierId, rank);
} }
@ -104,37 +107,41 @@ public class DictionaryPersistenceService {
@Transactional @Transactional
public void updateType(String typeId, TypeEntity typeValueRequest) { public void updateType(String typeId, TypeEntity typeValueRequest) {
typeRepository.findById(typeId).ifPresent(type -> { typeRepository.findById(typeId)
.ifPresent(type -> {
// if (type.isDeleted()) { // if (type.isDeleted()) {
// throw new NotFoundException("Type is deleted!"); // throw new NotFoundException("Type is deleted!");
// } // }
type.setVersion(type.getVersion() + 1); type.setVersion(type.getVersion() + 1);
checkRankAlreadyExists(type.getType(), type.getDossierTemplate().getId(), typeValueRequest.getRank(), type.getDossier() == null ? null : type.getDossier().getId()); checkRankAlreadyExists(type.getType(),
if (type.isSystemManaged()) { type.getDossierTemplate().getId(),
type.setHexColor(typeValueRequest.getHexColor()); typeValueRequest.getRank(),
type.setRecommendationHexColor(typeValueRequest.getRecommendationHexColor()); type.getDossier() == null ? null : type.getDossier().getId());
type.setSkippedHexColor(typeValueRequest.getSkippedHexColor()); if (type.isSystemManaged()) {
type.setDescription(typeValueRequest.getDescription()); type.setHexColor(typeValueRequest.getHexColor());
type.setLabel(typeValueRequest.getLabel()); type.setRecommendationHexColor(typeValueRequest.getRecommendationHexColor());
type.setAddToDictionaryAction(typeValueRequest.isAddToDictionaryAction()); type.setSkippedHexColor(typeValueRequest.getSkippedHexColor());
} else { type.setDescription(typeValueRequest.getDescription());
BeanUtils.copyProperties(typeValueRequest, type.setLabel(typeValueRequest.getLabel());
type, type.setAddToDictionaryAction(typeValueRequest.isAddToDictionaryAction());
"type", } else {
"dossierTemplateId", BeanUtils.copyProperties(typeValueRequest,
"dossierId", type,
"entries", "type",
"falsePositiveEntries", "dossierTemplateId",
"falseRecommendationEntries", "dossierId",
"dossierTemplate", "entries",
"dossier", "falsePositiveEntries",
"id", "falseRecommendationEntries",
"version", "dossierTemplate",
"dossierDictionaryOnly"); "dossier",
} "id",
typeRepository.save(type); "version",
}); "dossierDictionaryOnly");
}
typeRepository.save(type);
});
} }

View File

@ -14,8 +14,14 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
public interface TypeRepository extends JpaRepository<TypeEntity, String> { public interface TypeRepository extends JpaRepository<TypeEntity, String> {
@Query("select t from TypeEntity t where t.dossierTemplateId = :dossierTemplate and t.dossierId = :dossier and t.rank = :rank and t.softDeletedTime is null") @Query("select t from TypeEntity t where t.dossierTemplateId = :dossierTemplateId and "
Optional<TypeEntity> findOneByDossierTemplateIdAndDossierIdAndRank(@Param("dossierTemplate") String dossierTemplate, @Param("dossier") String dossier, @Param("rank") int rank); + "(CASE "
+ " WHEN :dossierId is null THEN t.dossierId is null "
+ " WHEN :dossierId is not null THEN t.dossierId = :dossierId "
+ "END) and t.rank = :rank and t.softDeletedTime is null")
List<TypeEntity> findByDossierTemplateIdAndDossierIdAndRank(@Param("dossierTemplateId") String dossierTemplateId,
@Param("dossierId") String dossierId,
@Param("rank") int rank);
List<TypeEntity> findByDossierId(String dossierId); List<TypeEntity> findByDossierId(String dossierId);
@ -24,6 +30,7 @@ public interface TypeRepository extends JpaRepository<TypeEntity, String> {
@Query("select t from TypeEntity t where t.id = :typeId and t.softDeletedTime is null") @Query("select t from TypeEntity t where t.id = :typeId and t.softDeletedTime is null")
Optional<TypeEntity> findByIdAndNotDeleted(@Param("typeId") String typeId); Optional<TypeEntity> findByIdAndNotDeleted(@Param("typeId") String typeId);
@Modifying @Modifying
@Query("update TypeEntity t set t.version = t.version + 1 where t.id = :typeId") @Query("update TypeEntity t set t.version = t.version + 1 where t.id = :typeId")
void updateByIdSetIncrementVersionByOne(@Param("typeId") String typeId); void updateByIdSetIncrementVersionByOne(@Param("typeId") String typeId);

View File

@ -50,13 +50,69 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
private List<String> testList2 = List.of("William C. Spare", "Charalampos", "Carina Wilson", "Patricia A. Sheehy", "William c. Spare", "carlsen", "PATRICIA A. SHEEHY"); private List<String> testList2 = List.of("William C. Spare", "Charalampos", "Carina Wilson", "Patricia A. Sheehy", "William c. Spare", "carlsen", "PATRICIA A. SHEEHY");
@BeforeEach @BeforeEach
public void createDossierRedactionDictionary() { public void createDossierRedactionDictionary() {
TenantContext.setTenantId("redaction"); TenantContext.setTenantId("redaction");
} }
@Test
public void testAddTypesWithSameRank() {
var dossier = dossierTesterAndProvider.provideTestDossier();
var dossierTemplate = dossierTemplateClient.getDossierTemplate(dossier.getDossierTemplateId());
var returnedtype1 = dictionaryClient.addType(CreateTypeValue.builder()
.type("test1")
.label("test1")
.hexColor("#fcba03")
.rank(100)
.hint(false)
.caseInsensitive(false)
.recommendation(false)
.addToDictionaryAction(true)
.dossierTemplateId(dossierTemplate.getId())
.dossierDictionaryOnly(false)
.build());
assertThat(returnedtype1.getRank()).isEqualTo(100);
Assertions.assertThrows(FeignException.Conflict.class,
() -> dictionaryClient.addType(CreateTypeValue.builder()
.type("test2")
.label("test2")
.hexColor("#fcba03")
.rank(100)
.hint(false)
.caseInsensitive(false)
.recommendation(false)
.addToDictionaryAction(true)
.dossierTemplateId(dossierTemplate.getId())
.dossierDictionaryOnly(false)
.build()));
var returnedtype2 = dictionaryClient.addType(CreateTypeValue.builder()
.type("test2")
.label("test2")
.hexColor("#fcba13")
.rank(50)
.hint(false)
.addToDictionaryAction(true)
.dossierTemplateId(dossierTemplate.getId())
.dossierDictionaryOnly(false)
.build());
assertThat(returnedtype2.getRank()).isEqualTo(50);
Assertions.assertThrows(FeignException.Conflict.class, () -> {
var request = new UpdateTypeValue();
BeanUtils.copyProperties(returnedtype1, request);
request.setRank(50);
dictionaryClient.updateType(returnedtype1.getType(), returnedtype1.getDossierTemplateId(), request);
});
}
@Test @Test
public void testAddEntriesToDossierTemplateDictionaryWithDossierDictionaryOnlyFlag() { public void testAddEntriesToDossierTemplateDictionaryWithDossierDictionaryOnlyFlag() {

View File

@ -108,7 +108,7 @@ public class EntityPerformanceTest extends AbstractPersistenceServerServiceTest
var template = dossierTemplateTesterAndProvider.provideTestTemplate("test"); var template = dossierTemplateTesterAndProvider.provideTestTemplate("test");
var type1 = typeProvider.testAndProvideType(template, null, "t1"); var type1 = typeProvider.testAndProvideType(template, null, "t1");
var type2 = typeProvider.testAndProvideType(template, null, "t2"); var type2 = typeProvider.testAndProvideType(template, null, "t2", false, 50);
List<DictionaryEntryEntity> type1Entries = entries.stream().map(s -> new DictionaryEntryEntity(0, s, 1, false, type1.getTypeId())).collect(Collectors.toList()); List<DictionaryEntryEntity> type1Entries = entries.stream().map(s -> new DictionaryEntryEntity(0, s, 1, false, type1.getTypeId())).collect(Collectors.toList());