diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DictionaryPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DictionaryPersistenceService.java index ce1191195..bef5984bc 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DictionaryPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DictionaryPersistenceService.java @@ -17,8 +17,8 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.BadRe 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.DossierTemplateRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.EntryRepository; 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.model.dossiertemplate.type.DictionarySummaryResponse; import lombok.RequiredArgsConstructor; diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierTemplatePersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierTemplatePersistenceService.java index bdd62b1b9..079b2b529 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierTemplatePersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierTemplatePersistenceService.java @@ -96,13 +96,19 @@ public class DossierTemplatePersistenceService { } + @Transactional public void validateDossierTemplateNameIsUnique(String templateName) { - getAllDossierTemplates().forEach(existing -> { - if (existing.getName().equals(templateName)) { - throw new ConflictException("DossierTemplate name must be unique"); - } - }); + if (isDossierTemplateNameNotUnique(templateName)) { + throw new ConflictException("DossierTemplate name must be unique"); + } + } + + + @Transactional + public boolean isDossierTemplateNameNotUnique(String templateName) { + + return dossierTemplateRepository.existsByName(templateName); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntryPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntryPersistenceService.java index b3d7deb0d..c56eeea2a 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntryPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntryPersistenceService.java @@ -12,10 +12,10 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.configur import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DictionaryEntryEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DictionaryFalsePositiveEntryEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DictionaryFalseRecommendationEntryEntity; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.EntryRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FalsePositiveEntryRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FalseRecommendationEntryRepository; 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.management.v1.processor.service.persistence.repository.dictionaryentry.FalsePositiveEntryRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalseRecommendationEntryRepository; import com.iqser.red.service.persistence.management.v1.processor.utils.jdbc.JDBCWriteUtils; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionaryEntryType; diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierTemplateRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierTemplateRepository.java index a094c6793..cb1ee1288 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierTemplateRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierTemplateRepository.java @@ -17,4 +17,7 @@ public interface DossierTemplateRepository extends JpaRepository findByIdAndNotDeleted(String dossierTemplateId); -} + + boolean existsByName(String name); + +} \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntryRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/EntryRepository.java similarity index 81% rename from persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntryRepository.java rename to persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/EntryRepository.java index 469e6bc02..c606916d7 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntryRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/EntryRepository.java @@ -1,7 +1,6 @@ -package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; import java.util.List; -import java.util.Set; import javax.transaction.Transactional; @@ -11,7 +10,7 @@ import org.springframework.data.jpa.repository.Query; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DictionaryEntryEntity; -public interface EntryRepository extends JpaRepository { +public interface EntryRepository extends EntryRepositoryCustom, JpaRepository { @Modifying @Query("update DictionaryEntryEntity e set e.deleted = true, e.version = :version where e.typeId = :typeId and e.value in :values") @@ -31,18 +30,11 @@ public interface EntryRepository extends JpaRepository findByTypeIdAndVersionGreaterThan(String typeId, long version); - @Modifying + @Modifying(flushAutomatically = true, clearAutomatically = true) @Transactional @Query("update DictionaryEntryEntity e set e.deleted = true, e.version = :version where e.typeId = :typeId") void deleteAllEntriesForTypeId(String typeId, long version); - - @Modifying(flushAutomatically = true, clearAutomatically = true) - @Transactional - @Query(value = "update dictionary_entry set deleted = false, version = :version where type_id = :typeId and value in (:entries) returning value", nativeQuery = true) - List undeleteEntries(String typeId, Set entries, long version); - - @Modifying(flushAutomatically = true, clearAutomatically = true) @Transactional @Query(value = "insert into dictionary_entry (value, version, deleted, type_id) " + " select value, 1, false, :newTypeId from dictionary_entry where type_id = :originalTypeId and deleted = false", nativeQuery = true) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/EntryRepositoryCustom.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/EntryRepositoryCustom.java new file mode 100644 index 000000000..fd74337a3 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/EntryRepositoryCustom.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; + +import java.util.List; +import java.util.Set; + +public interface EntryRepositoryCustom { + + List undeleteEntries(String typeId, Set entries, long version); + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/EntryRepositoryImpl.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/EntryRepositoryImpl.java new file mode 100644 index 000000000..e02d3d6ab --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/EntryRepositoryImpl.java @@ -0,0 +1,26 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; + +import java.util.List; +import java.util.Set; + +import org.springframework.stereotype.Repository; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import lombok.experimental.FieldDefaults; + +@RequiredArgsConstructor +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +@Repository +public class EntryRepositoryImpl implements EntryRepositoryCustom { + + QueryExecutor queryExecutor; + + + @Override + public List undeleteEntries(String typeId, Set entries, long version) { + + return queryExecutor.runUndeleteQueryInBatches(typeId, entries, version, "dictionary_entry"); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FalsePositiveEntryRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalsePositiveEntryRepository.java similarity index 77% rename from persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FalsePositiveEntryRepository.java rename to persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalsePositiveEntryRepository.java index c6d316ad4..103894b1f 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FalsePositiveEntryRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalsePositiveEntryRepository.java @@ -1,7 +1,6 @@ -package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; import java.util.List; -import java.util.Set; import javax.transaction.Transactional; @@ -11,7 +10,7 @@ import org.springframework.data.jpa.repository.Query; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DictionaryFalsePositiveEntryEntity; -public interface FalsePositiveEntryRepository extends JpaRepository { +public interface FalsePositiveEntryRepository extends FalsePositiveEntryRepositoryCustom, JpaRepository { @Modifying @Query("update DictionaryFalsePositiveEntryEntity e set e.deleted = true , e.version = :version where e.typeId = :typeId and e.value in :values") @@ -31,13 +30,6 @@ public interface FalsePositiveEntryRepository extends JpaRepository undeleteEntries(String typeId, Set entries, long version); - - @Modifying(flushAutomatically = true, clearAutomatically = true) @Transactional @Query(value = "insert into dictionary_false_positive_entry (value, version, deleted, type_id) " + " select value, 1, false, :newTypeId from dictionary_false_positive_entry where type_id = :originalTypeId and deleted = false", nativeQuery = true) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalsePositiveEntryRepositoryCustom.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalsePositiveEntryRepositoryCustom.java new file mode 100644 index 000000000..11e4c84ae --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalsePositiveEntryRepositoryCustom.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; + +import java.util.List; +import java.util.Set; + +public interface FalsePositiveEntryRepositoryCustom { + + List undeleteEntries(String typeId, Set entries, long version); + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalsePositiveEntryRepositoryImpl.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalsePositiveEntryRepositoryImpl.java new file mode 100644 index 000000000..718da46b3 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalsePositiveEntryRepositoryImpl.java @@ -0,0 +1,26 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; + +import java.util.List; +import java.util.Set; + +import org.springframework.stereotype.Repository; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import lombok.experimental.FieldDefaults; + +@RequiredArgsConstructor +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +@Repository +class FalsePositiveEntryRepositoryImpl implements FalsePositiveEntryRepositoryCustom { + + QueryExecutor queryExecutor; + + + @Override + public List undeleteEntries(String typeId, Set entries, long version) { + + return queryExecutor.runUndeleteQueryInBatches(typeId, entries, version, "dictionary_false_positive_entry"); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FalseRecommendationEntryRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalseRecommendationEntryRepository.java similarity index 77% rename from persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FalseRecommendationEntryRepository.java rename to persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalseRecommendationEntryRepository.java index 4f88393a7..833ad368b 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FalseRecommendationEntryRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalseRecommendationEntryRepository.java @@ -1,7 +1,6 @@ -package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; import java.util.List; -import java.util.Set; import javax.transaction.Transactional; @@ -11,7 +10,7 @@ import org.springframework.data.jpa.repository.Query; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DictionaryFalseRecommendationEntryEntity; -public interface FalseRecommendationEntryRepository extends JpaRepository { +public interface FalseRecommendationEntryRepository extends FalseRecommendationEntryRepositoryCustom, JpaRepository { @Modifying @Query("update DictionaryFalseRecommendationEntryEntity e set e.deleted = true , e.version = :version where e.typeId = :typeId and e.value in :values") @@ -32,12 +31,6 @@ public interface FalseRecommendationEntryRepository extends JpaRepository undeleteEntries(String typeId, Set entries, long version); - - @Modifying(flushAutomatically = true, clearAutomatically = true) @Transactional @Query(value = "insert into dictionary_false_recommendation_entry (value, version, deleted, type_id) " + " select value, 1, false, :newTypeId from dictionary_false_recommendation_entry where type_id = :originalTypeId and deleted = false", nativeQuery = true) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalseRecommendationEntryRepositoryCustom.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalseRecommendationEntryRepositoryCustom.java new file mode 100644 index 000000000..a1e45f536 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalseRecommendationEntryRepositoryCustom.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; + +import java.util.List; +import java.util.Set; + +public interface FalseRecommendationEntryRepositoryCustom { + + List undeleteEntries(String typeId, Set entries, long version); + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalseRecommendationEntryRepositoryImpl.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalseRecommendationEntryRepositoryImpl.java new file mode 100644 index 000000000..838df0665 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/FalseRecommendationEntryRepositoryImpl.java @@ -0,0 +1,26 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; + +import java.util.List; +import java.util.Set; + +import org.springframework.stereotype.Repository; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import lombok.experimental.FieldDefaults; + +@RequiredArgsConstructor +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +@Repository +class FalseRecommendationEntryRepositoryImpl implements FalseRecommendationEntryRepositoryCustom { + + QueryExecutor queryExecutor; + + + @Override + public List undeleteEntries(String typeId, Set entries, long version) { + + return queryExecutor.runUndeleteQueryInBatches(typeId, entries, version, "dictionary_false_recommendation_entry"); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/QueryExecutor.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/QueryExecutor.java new file mode 100644 index 000000000..354008eda --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/dictionaryentry/QueryExecutor.java @@ -0,0 +1,109 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.transaction.Transactional; + +import org.springframework.stereotype.Component; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import lombok.experimental.FieldDefaults; + +@RequiredArgsConstructor +@Component +@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) +class QueryExecutor { + + private static final String FETCH_ENTRY_VALUES_QUERY = """ + select value from ::tableName:: + where type_id = :typeId and value in (:entries)"""; + + private static final String UPDATE_ENTRIES_QUERY = """ + update ::tableName:: + set deleted = false, version = :version + where type_id = :typeId and value in (:entries)"""; + + // Currently (2023-04-13) there is a limitation in the Postgres JDBC driver, that limits the number of elements in a "IN" clause + // to the max value of a 'short'. We subtract a small value to be on the safe side, since it is unclear what contributes + // to the number of elements, only the elements or parentheses etc. + private static final int ELEMENT_CHUNK_SIZE = Short.MAX_VALUE - 10; + + EntityManager entityManager; + + + @Transactional + public LinkedList runUndeleteQueryInBatches(String typeId, Set entries, long version, String tableName) { + + var results = new LinkedList(); + + var entryList = new ArrayList<>(entries); + + for (int fromIndex = 0, toIndex = ELEMENT_CHUNK_SIZE; ; ) { + toIndex = Math.min(toIndex, entryList.size()); + + if (fromIndex >= entryList.size()) { + break; + } + + var values = entryList.subList(fromIndex, toIndex); + + var entryValues = executeFetchValuesQuery(typeId, tableName, values); + results.addAll(entryValues); + + executeUpdateQuery(typeId, version, tableName, values); + + fromIndex += ELEMENT_CHUNK_SIZE; + toIndex += ELEMENT_CHUNK_SIZE; + } + + return results; + } + + + private void executeUpdateQuery(String typeId, long version, String tableName, List values) { + + String updateSql = getUpdateEntriesQuery(tableName); + + Query updateEntriesQuery = entityManager.createNativeQuery(updateSql); + updateEntriesQuery.setParameter("typeId", typeId); + updateEntriesQuery.setParameter("version", version); + + updateEntriesQuery.setParameter("entries", values); + updateEntriesQuery.executeUpdate(); + } + + + // The call to query.getResultList returns an untyped list, there is no way around that. + // So we suppress the warning. + // CAUTION: Make sure that the query actually returns a list of Strings. + @SuppressWarnings("unchecked") + private List executeFetchValuesQuery(String typeId, String tableName, List values) { + + String fetchSql = getFetchEntryValuesQuery(tableName); + + Query fetchEntryValuesQuery = entityManager.createNativeQuery(fetchSql); + fetchEntryValuesQuery.setParameter("typeId", typeId); + + fetchEntryValuesQuery.setParameter("entries", values); + return fetchEntryValuesQuery.getResultList(); + } + + + private String getFetchEntryValuesQuery(String tableName) { + + return FETCH_ENTRY_VALUES_QUERY.replace("::tableName::", tableName); + } + + + private String getUpdateEntriesQuery(String tableName) { + + return UPDATE_ENTRIES_QUERY.replace("::tableName::", tableName); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/DossierTemplateImportService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/DossierTemplateImportService.java index a4c4bae97..c57727daa 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/DossierTemplateImportService.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/DossierTemplateImportService.java @@ -24,7 +24,6 @@ import java.util.stream.Collectors; import javax.transaction.Transactional; -import com.iqser.red.service.peristence.v1.server.settings.FileManagementServiceSettings; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; @@ -36,6 +35,7 @@ import org.springframework.web.bind.annotation.RequestBody; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.iqser.red.service.peristence.v1.server.settings.FileManagementServiceSettings; import com.iqser.red.service.peristence.v1.server.utils.FileUtils; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.BaseDictionaryEntry; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.ColorsEntity; @@ -376,22 +376,16 @@ public class DossierTemplateImportService { private void validateDossierTemplateName(DossierTemplate dossierTemplateMeta) { - boolean cond = true; - int index = 0; + int nameSuffix = 0; String dossierTemplateName = dossierTemplateMeta.getName(); - do { - try { - dossierTemplatePersistenceService.validateDossierTemplateNameIsUnique(dossierTemplateMeta.getName()); - cond = false; - } catch (ConflictException e) { - if (index == 0) { - dossierTemplateMeta.setName("Copy of " + dossierTemplateName); - } else { - dossierTemplateMeta.setName("Copy of " + dossierTemplateName + " - " + index); - } - index++; + while (dossierTemplatePersistenceService.isDossierTemplateNameNotUnique(dossierTemplateMeta.getName())) { + if (nameSuffix == 0) { + dossierTemplateMeta.setName("Copy of " + dossierTemplateName); + } else { + dossierTemplateMeta.setName("Copy of " + dossierTemplateName + " - " + nameSuffix); } - } while (cond); + nameSuffix++; + } } @@ -449,10 +443,8 @@ public class DossierTemplateImportService { dictionaryPersistenceService.incrementVersion(typeId); typeIdsAdded.add(typeId); // added to the list, since the type can not be deleted }); - Set typesToRemove = currentTypes.stream() - .filter(t -> !t.isDeleted()) // remove the ones already soft deleted - .map(TypeEntity::getId) - .filter(t -> !typeIdsAdded.contains(t)) // exclude the type ids already added from the import + Set typesToRemove = currentTypes.stream().filter(t -> !t.isDeleted()) // remove the ones already soft deleted + .map(TypeEntity::getId).filter(t -> !typeIdsAdded.contains(t)) // exclude the type ids already added from the import .filter(t -> !currentTypesIdSystemManaged.contains(t)) // exclude the types system managed .collect(Collectors.toSet()); typesToRemove.forEach(dictionaryService::deleteType); @@ -568,7 +560,7 @@ public class DossierTemplateImportService { double compressionRatio = (float) totalSizeEntry / ze.getCompressedSize(); if (compressionRatio > settings.getCompressionThresholdRatio()) { - log.debug("zip entry: " + ze.getName() + " - totalSizeEntry: " + totalSizeEntry + " ze.getCompressedSize(): " + ze.getCompressedSize() + " compressionRatio: " + compressionRatio); + log.debug("zip entry: " + ze.getName() + " - totalSizeEntry: " + totalSizeEntry + " ze.getCompressedSize(): " + ze.getCompressedSize() + " compressionRatio: " + compressionRatio); // ratio between compressed and uncompressed data is highly suspicious, looks like a Zip Bomb Attack throw new BadRequestException("ZIP-Bomb detected (compressionRatio)."); } diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/performance/EntityPerformanceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/performance/EntityPerformanceTest.java index 13c16e7a6..6fe915223 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/performance/EntityPerformanceTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/performance/EntityPerformanceTest.java @@ -15,7 +15,7 @@ import com.iqser.red.service.peristence.v1.server.integration.service.DossierTem 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.service.persistence.repository.EntryRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.EntryRepository; import com.iqser.red.service.persistence.management.v1.processor.utils.jdbc.JDBCWriteUtils; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.CloneDossierTemplateRequest; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionaryEntryType; diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java index b8a12e816..0b5e28acf 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java @@ -54,9 +54,6 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierStatusRepository; 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.DownloadStatusRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.EntryRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FalsePositiveEntryRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FalseRecommendationEntryRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributeConfigRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributesGeneralConfigurationRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributesRepository; @@ -76,6 +73,9 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist 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.ViewedPagesRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.WatermarkRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.EntryRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalsePositiveEntryRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalseRecommendationEntryRepository; import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.configuration.ApplicationConfig; import com.iqser.red.service.persistence.service.v1.api.model.multitenancy.TenantRequest; @@ -182,7 +182,6 @@ public abstract class AbstractPersistenceServerServiceTest { protected PrometheusMeterRegistry prometheusMeterRegistry; - @Before public void setupOptimize() {