Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit db2f29f

Browse files
committed
3578-add prepared statements
1 parent 0d32dd7 commit db2f29f

2 files changed

Lines changed: 62 additions & 34 deletions

File tree

sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Collections;
2929
import java.util.Comparator;
3030
import java.util.Date;
31+
import java.util.LinkedList;
3132
import java.util.List;
3233
import java.util.Map;
3334
import java.util.Optional;
@@ -156,9 +157,9 @@
156157
import de.symeda.sormas.backend.user.UserService;
157158
import de.symeda.sormas.backend.util.DateHelper8;
158159
import de.symeda.sormas.backend.util.DtoHelper;
160+
import de.symeda.sormas.backend.util.IterableHelper;
159161
import de.symeda.sormas.backend.util.ModelConstants;
160162
import de.symeda.sormas.backend.util.Pseudonymizer;
161-
import de.symeda.sormas.backend.util.QueryHelper;
162163
import de.symeda.sormas.backend.visit.Visit;
163164
import de.symeda.sormas.backend.visit.VisitService;
164165

@@ -970,23 +971,36 @@ public int[] getContactCountsByCasesForDashboard(List<Long> contactIds) {
970971
}
971972
}
972973

974+
@SuppressWarnings("JpaQueryApiInspection")
973975
@Override
974976
public int getNonSourceCaseCountForDashboard(List<String> caseUuids) {
975977

976978
if (CollectionUtils.isEmpty(caseUuids)) {
977979
// Avoid empty IN clause
978980
return 0;
981+
} else if (caseUuids.size() > ModelConstants.PARAMETER_LIMIT) {
982+
List<BigInteger> countResults = new LinkedList<>();
983+
IterableHelper.executeBatched(caseUuids, ModelConstants.PARAMETER_LIMIT, batchedCaseUuids -> {
984+
Query query = em.createNativeQuery(
985+
String.format(
986+
"SELECT DISTINCT count(case1_.id) FROM contact AS contact0_ LEFT OUTER JOIN cases AS case1_ ON (contact0_.%s_id = case1_.id) WHERE case1_.%s IN (:uuidList)",
987+
Contact.RESULTING_CASE.toLowerCase(),
988+
Case.UUID));
989+
query.setParameter("uuidList", batchedCaseUuids);
990+
countResults.add((BigInteger) query.getSingleResult());
991+
});
992+
return countResults.stream().collect(Collectors.summingInt(BigInteger::intValue));
993+
} else {
994+
Query query = em.createNativeQuery(
995+
String.format(
996+
"SELECT DISTINCT count(case1_.id) FROM contact AS contact0_ LEFT OUTER JOIN cases AS case1_ ON (contact0_.%s_id = case1_.id) WHERE case1_.%s IN (:uuidList)",
997+
Contact.RESULTING_CASE.toLowerCase(),
998+
Case.UUID));
999+
query.setParameter("uuidList", caseUuids);
1000+
BigInteger count = (BigInteger) query.getSingleResult();
1001+
return count.intValue();
9791002
}
9801003

981-
Query query = em.createNativeQuery(
982-
String.format(
983-
"SELECT DISTINCT count(case1_.id) FROM contact AS contact0_ LEFT OUTER JOIN cases AS case1_ ON (contact0_.%s_id = case1_.id) WHERE case1_.%s IN (%s)",
984-
Contact.RESULTING_CASE.toLowerCase(),
985-
Case.UUID,
986-
QueryHelper.concatStrings(caseUuids)));
987-
988-
BigInteger count = (BigInteger) query.getSingleResult();
989-
return count.intValue();
9901004
}
9911005

9921006
public Contact fromDto(@NotNull ContactDto source) {
@@ -1016,10 +1030,9 @@ public Contact fromDto(@NotNull ContactDto source) {
10161030

10171031
// use only date, not time
10181032
target.setMultiDayContact(source.isMultiDayContact());
1019-
if(source.isMultiDayContact()) {
1020-
target.setFirstContactDate(source.getFirstContactDate() != null ?
1021-
DateHelper8.toDate(DateHelper8.toLocalDate(source.getFirstContactDate())) :
1022-
null);
1033+
if (source.isMultiDayContact()) {
1034+
target.setFirstContactDate(
1035+
source.getFirstContactDate() != null ? DateHelper8.toDate(DateHelper8.toLocalDate(source.getFirstContactDate())) : null);
10231036
} else {
10241037
target.setFirstContactDate(null);
10251038
}

sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.math.BigInteger;
2121
import java.util.Date;
2222
import java.util.HashMap;
23+
import java.util.LinkedList;
2324
import java.util.List;
2425
import java.util.Map;
2526
import java.util.stream.Collectors;
@@ -38,6 +39,8 @@
3839
import javax.persistence.criteria.Predicate;
3940
import javax.persistence.criteria.Root;
4041

42+
import de.symeda.sormas.backend.util.IterableHelper;
43+
import de.symeda.sormas.backend.util.ModelConstants;
4144
import org.apache.commons.collections.CollectionUtils;
4245

4346
import de.symeda.sormas.api.EntityRelevanceStatus;
@@ -243,26 +246,38 @@ public Map<PathogenTestResultType, Long> getNewTestResultCountByResultType(List<
243246
// Avoid parameter limit by joining caseIds to a String instead of n parameters
244247
StringBuilder queryBuilder = new StringBuilder();
245248
//@formatter:off
246-
queryBuilder.append("WITH sortedsamples AS (SELECT DISTINCT ON (").append(Sample.ASSOCIATED_CASE).append("_id) ")
247-
.append(Sample.ASSOCIATED_CASE).append("_id, ").append(Sample.PATHOGEN_TEST_RESULT).append(", ").append(Sample.SAMPLE_DATE_TIME)
248-
.append(" FROM ").append(Sample.TABLE_NAME).append(" WHERE (").append(Sample.SPECIMEN_CONDITION).append(" IS NULL OR ")
249-
.append(Sample.SPECIMEN_CONDITION).append(" = '").append(SpecimenCondition.ADEQUATE.name()).append("') AND ").append(Sample.TABLE_NAME)
250-
.append(".").append(Sample.DELETED).append(" = false ORDER BY ").append(Sample.ASSOCIATED_CASE).append("_id, ")
251-
.append(Sample.SAMPLE_DATE_TIME).append(" desc) SELECT sortedsamples.").append(Sample.PATHOGEN_TEST_RESULT).append(", COUNT(")
252-
.append(Sample.ASSOCIATED_CASE).append("_id) FROM sortedsamples JOIN ").append(Case.TABLE_NAME).append(" ON sortedsamples.")
253-
.append(Sample.ASSOCIATED_CASE).append("_id = ").append(Case.TABLE_NAME).append(".id ")
254-
.append(" WHERE sortedsamples.").append(Sample.ASSOCIATED_CASE).append("_id IN (").append(QueryHelper.concatLongs(caseIds)).append(") ")
255-
.append(" GROUP BY sortedsamples." + Sample.PATHOGEN_TEST_RESULT);
256-
//@formatter:on
257-
258-
Query query = em.createNativeQuery(queryBuilder.toString());
259-
260-
@SuppressWarnings("unchecked")
261-
List<Object[]> results = query.getResultList();
262-
263-
return results.stream()
264-
.filter(e -> e[0] != null)
265-
.collect(Collectors.toMap(e -> PathogenTestResultType.valueOf((String) e[0]), e -> ((BigInteger) e[1]).longValue()));
249+
queryBuilder.append("WITH sortedsamples AS (SELECT DISTINCT ON (").append(Sample.ASSOCIATED_CASE).append("_id) ")
250+
.append(Sample.ASSOCIATED_CASE).append("_id, ").append(Sample.PATHOGEN_TEST_RESULT).append(", ").append(Sample.SAMPLE_DATE_TIME)
251+
.append(" FROM ").append(Sample.TABLE_NAME).append(" WHERE (").append(Sample.SPECIMEN_CONDITION).append(" IS NULL OR ")
252+
.append(Sample.SPECIMEN_CONDITION).append(" = '").append(SpecimenCondition.ADEQUATE.name()).append("') AND ").append(Sample.TABLE_NAME)
253+
.append(".").append(Sample.DELETED).append(" = false ORDER BY ").append(Sample.ASSOCIATED_CASE).append("_id, ")
254+
.append(Sample.SAMPLE_DATE_TIME).append(" desc) SELECT sortedsamples.").append(Sample.PATHOGEN_TEST_RESULT).append(", COUNT(")
255+
.append(Sample.ASSOCIATED_CASE).append("_id) FROM sortedsamples JOIN ").append(Case.TABLE_NAME).append(" ON sortedsamples.")
256+
.append(Sample.ASSOCIATED_CASE).append("_id = ").append(Case.TABLE_NAME).append(".id ")
257+
.append(" WHERE sortedsamples.").append(Sample.ASSOCIATED_CASE).append("_id IN (:caseIds)")
258+
.append(" GROUP BY sortedsamples." + Sample.PATHOGEN_TEST_RESULT);
259+
//@formatter:on
260+
261+
if (caseIds.size() < ModelConstants.PARAMETER_LIMIT) {
262+
List<Object[]> results;
263+
Query query = em.createNativeQuery(queryBuilder.toString());
264+
query.setParameter("caseIds", caseIds);
265+
results = query.getResultList();
266+
267+
return results.stream()
268+
.filter(e -> e[0] != null)
269+
.collect(Collectors.toMap(e -> PathogenTestResultType.valueOf((String) e[0]), e -> ((BigInteger) e[1]).longValue()));
270+
} else {
271+
List<Object[]> results = new LinkedList<>();
272+
IterableHelper.executeBatched(caseIds, ModelConstants.PARAMETER_LIMIT, batchedCaseIds -> {
273+
Query query = em.createNativeQuery(queryBuilder.toString());
274+
query.setParameter("caseIds", batchedCaseIds);
275+
results.addAll(query.getResultList());
276+
});
277+
return results.stream()
278+
.filter(e -> e[0] != null)
279+
.collect(Collectors.toMap(e -> PathogenTestResultType.valueOf((String) e[0]), e -> ((BigInteger) e[1]).longValue()));
280+
}
266281
}
267282

268283
@Override

0 commit comments

Comments
 (0)