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

View File

@ -2,6 +2,8 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis
import java.util.List; import java.util.List;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; 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); 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 java.util.List;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
@ -27,4 +29,10 @@ public interface FalsePositiveEntryRepository extends JpaRepository<DictionaryFa
List<DictionaryFalsePositiveEntryEntity> findByTypeIdAndVersionGreaterThan(String typeId, long version); 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 java.util.List;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
@ -28,4 +30,10 @@ public interface FalseRecommendationEntryRepository extends JpaRepository<Dictio
List<DictionaryFalseRecommendationEntryEntity> findByTypeIdAndVersionGreaterThan(String typeId, long version); 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); var currentVersion = getCurrentVersion(typeResult);
List<String> existing = entryPersistenceService.getEntries(typeId, dictionaryEntryType, null) if (removeCurrent) {
List<String> existing = entryPersistenceService.getEntries(typeId, dictionaryEntryType, null)
.stream() .stream()
.filter(e -> !e.isDeleted()) .filter(e -> !e.isDeleted())
.map(BaseDictionaryEntry::getValue) .map(BaseDictionaryEntry::getValue)
.collect(toList()); .collect(toList());
if (removeCurrent) {
List<String> removed = new ArrayList<>(existing); List<String> removed = new ArrayList<>(existing);
removed.removeAll(cleanEntries); removed.removeAll(cleanEntries);
@ -97,13 +96,7 @@ public class DictionaryController implements DictionaryResource {
entryPersistenceService.addEntry(typeId, added, currentVersion + 1, dictionaryEntryType); entryPersistenceService.addEntry(typeId, added, currentVersion + 1, dictionaryEntryType);
} else { } else {
entryPersistenceService.addEntry(typeId, new ArrayList<>(cleanEntries), currentVersion + 1, dictionaryEntryType);
List<String> added = new ArrayList<>(cleanEntries);
added.removeAll(existing);
if (added.isEmpty()) {
return;
}
entryPersistenceService.addEntry(typeId, added, currentVersion + 1, dictionaryEntryType);
} }
dictionaryPersistenceService.incrementVersion(typeId); 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 file: db/changelog/22-add-soft-delete-time-to-entity.changelog.yaml
- include: - include:
file: db/changelog/23-quartz.changelog.yaml 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.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.*; import java.util.*;
@ -105,8 +106,13 @@ public class FilePerformanceTest extends AbstractPersistenceServerServiceTest {
de.setValue("Dictionary Entry" + i); de.setValue("Dictionary Entry" + i);
des.add(de); 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()); log.info("Created Type: {}", te.getType());
} }