RED-3716: On adding entries to a dictionary do not read the whole dictionary from persistence

This commit is contained in:
aoezyetimoglu 2022-04-20 15:45:38 +02:00
parent 4d12c996bd
commit 30d40816ae
8 changed files with 76 additions and 23 deletions

View File

@ -11,9 +11,12 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionaryEntryType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@ -34,34 +37,43 @@ public class EntryPersistenceService {
switch (dictionaryEntryType) {
case ENTRY:
var dictionaryEntries = entries.stream().map(word -> {
entries.stream().forEach(word -> {
DictionaryEntryEntity entry = new DictionaryEntryEntity();
entry.setVersion(version);
entry.setValue(word);
entry.setType(type);
return entry;
}).collect(Collectors.toList());
entryRepository.saveAll(dictionaryEntries);
try {
entryRepository.save(entry);
} catch (DataIntegrityViolationException e) {
entryRepository.undeleteEntryIfDeleted(typeId, entry.getValue(), version);
}
});
break;
case FALSE_POSITIVE:
var dictionaryFalsePositiveEntries = entries.stream().map(word -> {
entries.stream().forEach(word -> {
DictionaryFalsePositiveEntryEntity entry = new DictionaryFalsePositiveEntryEntity();
entry.setVersion(version);
entry.setValue(word);
entry.setType(type);
return entry;
}).collect(Collectors.toList());
falsePositiveEntryRepository.saveAll(dictionaryFalsePositiveEntries);
try {
falsePositiveEntryRepository.save(entry);
} catch (DataIntegrityViolationException e) {
falsePositiveEntryRepository.undeleteEntryIfDeleted(typeId, entry.getValue(), version);
}
});
break;
case FALSE_RECOMMENDATION:
var dictionaryFalseRecommendationsEntries = entries.stream().map(word -> {
entries.stream().forEach(word -> {
DictionaryFalseRecommendationEntryEntity entry = new DictionaryFalseRecommendationEntryEntity();
entry.setVersion(version);
entry.setValue(word);
entry.setType(type);
return entry;
}).collect(Collectors.toList());
falseRecommendationEntryRepository.saveAll(dictionaryFalseRecommendationsEntries);
try {
falseRecommendationEntryRepository.save(entry);
} catch (DataIntegrityViolationException e) {
falseRecommendationEntryRepository.undeleteEntryIfDeleted(typeId, entry.getValue(), version);
}
});
break;
}
}

View File

@ -2,6 +2,8 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
@ -26,4 +28,9 @@ public interface EntryRepository extends JpaRepository<DictionaryEntryEntity, Lo
List<DictionaryEntryEntity> findByTypeIdAndVersionGreaterThan(String typeId, long version);
@Modifying
@Transactional
@Query("update DictionaryEntryEntity e set e.deleted = false, e.version = :version where e.type.id =:typeId and e.value = :value and e.deleted = true")
void undeleteEntryIfDeleted(String typeId, String value, long version);
}

View File

@ -2,6 +2,8 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
@ -27,4 +29,10 @@ public interface FalsePositiveEntryRepository extends JpaRepository<DictionaryFa
List<DictionaryFalsePositiveEntryEntity> findByTypeIdAndVersionGreaterThan(String typeId, long version);
@Modifying
@Transactional
@Query("update DictionaryFalsePositiveEntryEntity e set e.deleted = false, e.version = :version where e.type.id =:typeId and e.value = :value and e.deleted = true")
void undeleteEntryIfDeleted(String typeId, String value, long version);
}

View File

@ -2,6 +2,8 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
@ -28,4 +30,10 @@ public interface FalseRecommendationEntryRepository extends JpaRepository<Dictio
List<DictionaryFalseRecommendationEntryEntity> findByTypeIdAndVersionGreaterThan(String typeId, long version);
@Modifying
@Transactional
@Query("update DictionaryFalseRecommendationEntryEntity e set e.deleted = false, e.version = :version where e.type.id =:typeId and e.value = :value and e.deleted = true")
void undeleteEntryIfDeleted(String typeId, String value, long version);
}

View File

@ -79,14 +79,13 @@ public class DictionaryController implements DictionaryResource {
var currentVersion = getCurrentVersion(typeResult);
List<String> existing = entryPersistenceService.getEntries(typeId, dictionaryEntryType, null)
if (removeCurrent) {
List<String> existing = entryPersistenceService.getEntries(typeId, dictionaryEntryType, null)
.stream()
.filter(e -> !e.isDeleted())
.map(BaseDictionaryEntry::getValue)
.collect(toList());
if (removeCurrent) {
List<String> removed = new ArrayList<>(existing);
removed.removeAll(cleanEntries);
@ -97,13 +96,7 @@ public class DictionaryController implements DictionaryResource {
entryPersistenceService.addEntry(typeId, added, currentVersion + 1, dictionaryEntryType);
} else {
List<String> added = new ArrayList<>(cleanEntries);
added.removeAll(existing);
if (added.isEmpty()) {
return;
}
entryPersistenceService.addEntry(typeId, added, currentVersion + 1, dictionaryEntryType);
entryPersistenceService.addEntry(typeId, new ArrayList<>(cleanEntries), currentVersion + 1, dictionaryEntryType);
}
dictionaryPersistenceService.incrementVersion(typeId);

View File

@ -0,0 +1,17 @@
databaseChangeLog:
- changeSet:
id: add-unique-constraint-for-dictionary
author: ali
changes:
- addUniqueConstraint:
columnNames: value, type_id
constraintName: unique_constraint_dictionary_false_recommendation_entry
tableName: dictionary_false_recommendation_entry
- addUniqueConstraint:
columnNames: value, type_id
constraintName: unique_constraint_dictionary_entry
tableName: dictionary_entry
- addUniqueConstraint:
columnNames: value, type_id
constraintName: unique_constraint_dictionary_false_positive_entry
tableName: dictionary_false_positive_entry

View File

@ -55,3 +55,5 @@ databaseChangeLog:
file: db/changelog/22-add-soft-delete-time-to-entity.changelog.yaml
- include:
file: db/changelog/23-quartz.changelog.yaml
- include:
file: db/changelog/24-add-unique-constraint-for-dictionary.yaml

View File

@ -17,6 +17,7 @@ import org.assertj.core.util.Sets;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import java.time.OffsetDateTime;
import java.util.*;
@ -105,8 +106,13 @@ public class FilePerformanceTest extends AbstractPersistenceServerServiceTest {
de.setValue("Dictionary Entry" + i);
des.add(de);
try {
entryRepository.save(de);
} catch (DataIntegrityViolationException e) {
log.info("Duplicate Type: {}", te.getType());
entryRepository.undeleteEntryIfDeleted(te.getId(), de.getValue(), de.getVersion());
}
}
entryRepository.saveAll(des);
log.info("Created Type: {}", te.getType());
}