Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ public int updateCatDimensionCategoryRefs(
set categoryid = :targetCategoryId
where cd.categoryid in :sourceCategoryIds
""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
.setParameter("targetCategoryId", targetCategoryId)
.setParameter("sourceCategoryIds", sourceCategoryIds)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(5000))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.List;
import java.util.Set;
import org.hibernate.LockOptions;
import org.hisp.dhis.category.Category;
import org.hisp.dhis.category.CategoryCombo;
import org.hisp.dhis.category.CategoryComboStore;
import org.hisp.dhis.common.DataDimensionType;
Expand Down Expand Up @@ -96,8 +97,11 @@ public int updateCatComboCategoryRefs(Set<Long> sourceCategoryIds, long targetCa
set categoryid = :targetCategoryId
where cc_c.categoryid in :sourceCategoryIds
""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
// categorycombos_categories backs both the cached CategoryCombo.categories and
// Category.categoryCombos collections. Collection regions are keyed by the collection's
// element entity, so naming both entities is what reaches both regions.
.addSynchronizedEntityClass(Category.class)
.setParameter("targetCategoryId", targetCategoryId)
.setParameter("sourceCategoryIds", sourceCategoryIds)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(5000))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import javax.annotation.Nonnull;
import org.hibernate.LockOptions;
import org.hisp.dhis.category.Category;
import org.hisp.dhis.category.CategoryOption;
import org.hisp.dhis.category.CategoryStore;
import org.hisp.dhis.common.DataDimensionType;
import org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore;
Expand Down Expand Up @@ -118,8 +119,11 @@ public int removeCatOptionCategoryRefs(Set<Long> sourceCategoryIds) {
delete from categories_categoryoptions c_co
where c_co.categoryid in :sourceCategoryIds
""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
// categories_categoryoptions is the Category.categoryOptions collection table. Collection
// regions are keyed by the collection's element entity, so CategoryOption is what reaches
// that region, not the owning Category.
.addSynchronizedEntityClass(CategoryOption.class)
.setParameter("sourceCategoryIds", sourceCategoryIds)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(5000))
.executeUpdate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ public int updateCategoryComboRefs(Set<Long> sourceCategoryComboIds, long target
set categorycomboid = :targetCategoryComboId
where categorycomboid in :sourceCategoryComboIds
""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
.setParameter("targetCategoryComboId", targetCategoryComboId)
.setParameter("sourceCategoryComboIds", sourceCategoryComboIds)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(5000))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ public void deleteCompleteDataSetRegistration(
AND c.sourceid = (SELECT organisationunitid FROM organisationunit ou WHERE ou.uid = :ou)
AND c.attributeoptioncomboid = (SELECT categoryoptioncomboid FROM categoryoptioncombo aoc WHERE aoc.uid = :aoc)
""";
entityManager
.createNativeQuery(sql)
nativeSynchronizedQuery(sql)
.setParameter("ds", dataSet.getValue())
.setParameter("pe", period.getIsoDate())
.setParameter("ou", orgUnit.getValue())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,11 @@ public int updateDataSetElementCategoryComboRefs(
set categorycomboid = :targetCategoryComboId
where categorycomboid in :sourceCategoryComboIds
""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
// datasetelement is DataSetElement's own table. It is also the DataSet.dataSetElements
// collection table, and since collection regions are keyed by the collection's element
// entity, naming DataSetElement reaches that cached collection too.
.addSynchronizedEntityClass(DataSetElement.class)
.setParameter("targetCategoryComboId", targetCategoryComboId)
.setParameter("sourceCategoryComboIds", sourceCategoryComboIds)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(5000))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void deleteByOrgUnit(@Nonnull UID orgUnit) {
DELETE FROM datavalueaudit dva
WHERE dva.organisationunitid = (SELECT ou.organisationunitid FROM organisationunit ou WHERE ou.uid = :ou)""";

entityManager.createNativeQuery(sql).setParameter("ou", orgUnit.getValue()).executeUpdate();
nativeSynchronizedQuery(sql).setParameter("ou", orgUnit.getValue()).executeUpdate();
}

@Override
Expand All @@ -83,7 +83,7 @@ public void deleteByDataElement(@Nonnull UID dataElement) {
DELETE FROM datavalueaudit dva
WHERE dva.dataelementid = (SELECT de.dataelementid FROM dataelement de WHERE de.uid = :de)""";

entityManager.createNativeQuery(sql).setParameter("de", dataElement.getValue()).executeUpdate();
nativeSynchronizedQuery(sql).setParameter("de", dataElement.getValue()).executeUpdate();
}

@Override
Expand All @@ -93,8 +93,7 @@ public void deleteByOptionCombo(@Nonnull UID categoryOptionCombo) {
DELETE FROM datavalueaudit dva
WHERE dva.categoryoptioncomboid = (SELECT categoryoptioncomboid FROM categoryoptioncombo WHERE uid = :coc)
OR dva.attributeoptioncomboid = (SELECT categoryoptioncomboid FROM categoryoptioncombo WHERE uid = :coc);""";
entityManager
.createNativeQuery(sql)
nativeSynchronizedQuery(sql)
.setParameter("coc", categoryOptionCombo.getValue())
.executeUpdate();
}
Expand Down Expand Up @@ -258,14 +257,16 @@ IF NOT EXISTS (
END IF;
END;
$$""";
getSession().createNativeQuery(sql).executeUpdate();
// DDL, not entity persistence, so it skips Hibernate and its cache invalidation
jdbcTemplate.execute(sql);
}

@Override
public void disableAudit() {
String sql =
"""
DROP TRIGGER IF EXISTS trg_datavalue_audit ON datavalue""";
getSession().createNativeQuery(sql).executeUpdate();
// DDL, not entity persistence, so it skips Hibernate and its cache invalidation
jdbcTemplate.execute(sql);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ public int updateDeletedIfNotZeroIsSignificant() {
AND de.zeroissignificant = false
AND dv.dataelementid = de.dataelementid
AND (dv.value IS NULL OR dv.value = '')""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(1000))
.executeUpdate();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ INSERT INTO period (periodid, periodtypeid, startdate, enddate, iso)
if (pk != null) {
return pk;
}
session
.createNativeQuery(sql2)
nativeSynchronizedQuery(session, sql2)
.setParameter("type", period.getPeriodType().getName())
.setParameter("start", period.getStartDate())
.setParameter("end", period.getEndDate())
Expand All @@ -144,8 +143,7 @@ INSERT INTO period (periodid, periodtypeid, startdate, enddate, iso)
public void delete(@Nonnull Period period) {
String isoDate = period.getIsoDate();
int deleted =
getSession()
.createNativeQuery("DELETE FROM period where iso = :iso")
nativeSynchronizedQuery("DELETE FROM period where iso = :iso")
.setParameter("iso", isoDate)
.executeUpdate();
if (deleted > 0) {
Expand Down Expand Up @@ -261,7 +259,12 @@ INSERT INTO periodtype (periodtypeid, name)
if (pk != null) {
return pk;
}
session.createNativeQuery(sql2).setParameter("name", name).executeUpdate();
session
.createNativeQuery(sql2)
// PeriodType, not the store's own Period
.addSynchronizedEntityClass(PeriodType.class)
.setParameter("name", name)
.executeUpdate();
return session.createNativeQuery("SELECT lastval()").uniqueResult();
});
if (id instanceof Number n) {
Expand All @@ -286,6 +289,7 @@ public void updatePeriodType(PeriodType periodType) {
session ->
session
.createNativeQuery(sql)
.addSynchronizedEntityClass(PeriodType.class)
.setParameter("name", name)
.setParameter("label", label)
.executeUpdate());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,7 @@ WHEN attributecomboid IN (:sourceCategoryComboIds)
categorycomboid IN (:sourceCategoryComboIds)
OR attributecomboid IN (:sourceCategoryComboIds);
""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
.setParameter("targetCategoryComboId", targetCategoryComboId)
.setParameter("sourceCategoryComboIds", sourceCategoryComboIds)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(5000))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.hibernate.query.NativeQuery;
import org.hisp.dhis.common.UID;
import org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore;
import org.hisp.dhis.fileresource.FileResource;
import org.hisp.dhis.hibernate.jsonb.type.JsonJobParametersType;
import org.hisp.dhis.security.acl.AclService;
import org.springframework.context.ApplicationEventPublisher;
Expand Down Expand Up @@ -385,7 +386,10 @@ public boolean tryExecuteNow(@Nonnull UID jobId) {
and (schedulingtype != 'ONCE_ASAP' or lastfinished is null)
""";
return runWriteInStatelessSession(
q -> q.createNativeQuery(sql).setParameter("id", jobId.getValue()).executeUpdate())
q ->
nativeSynchronizedQuery(q, sql)
.setParameter("id", jobId.getValue())
.executeUpdate())
> 0;
}

Expand Down Expand Up @@ -413,7 +417,10 @@ and not exists (
)
""";
return runWriteInStatelessSession(
q -> q.createNativeQuery(sql).setParameter("id", jobId.getValue()).executeUpdate())
q ->
nativeSynchronizedQuery(q, sql)
.setParameter("id", jobId.getValue())
.executeUpdate())
> 0;
}

Expand Down Expand Up @@ -444,7 +451,10 @@ public boolean tryCancel(@Nonnull UID jobId) {
)
""";
return runWriteInStatelessSession(
q -> q.createNativeQuery(sql).setParameter("id", jobId.getValue()).executeUpdate())
q ->
nativeSynchronizedQuery(q, sql)
.setParameter("id", jobId.getValue())
.executeUpdate())
> 0;
}

Expand Down Expand Up @@ -475,7 +485,7 @@ public boolean tryFinish(@Nonnull UID jobId, JobStatus status) {
""";
return runWriteInStatelessSession(
q ->
q.createNativeQuery(sql)
nativeSynchronizedQuery(q, sql)
.setParameter("id", jobId.getValue())
.setParameter("status", status.name())
.executeUpdate())
Expand Down Expand Up @@ -503,7 +513,7 @@ public boolean trySkip(@Nonnull String queue) {
or lastexecuted < (select lastexecuted from jobconfiguration where queuename = :queue and queueposition = 0 limit 1))
""";
return runWriteInStatelessSession(
q -> q.createNativeQuery(sql).setParameter("queue", queue).executeUpdate())
q -> nativeSynchronizedQuery(q, sql).setParameter("queue", queue).executeUpdate())
> 0;
}

Expand All @@ -521,7 +531,7 @@ public void updateProgress(
""";
runWriteInStatelessSession(
q ->
q.createNativeQuery(sql)
nativeSynchronizedQuery(q, sql)
.setParameter("id", jobId.getValue())
.setParameter("json", progressJson)
.setParameter("errors", errorCodes)
Expand All @@ -539,7 +549,7 @@ public int updateDisabledJobs() {
where jobstatus = 'SCHEDULED'
and enabled = false
""";
return runWriteInStatelessSession(q -> q.createNativeQuery(sql).executeUpdate());
return runWriteInStatelessSession(q -> nativeSynchronizedQuery(q, sql).executeUpdate());
}

@Override
Expand All @@ -557,7 +567,7 @@ and now() > lastfinished + :ttl * interval '1 minute'
int deletedCount =
runWriteInStatelessSession(
q ->
q.createNativeQuery(sql)
nativeSynchronizedQuery(q, sql)
.setLockOptions(new LockOptions(LockMode.PESSIMISTIC_WRITE).setTimeOut(2000))
.setParameter("ttl", max(1, ttlMinutes))
.executeUpdate());
Expand All @@ -575,6 +585,7 @@ and uid not in (select uid from jobconfiguration where schedulingtype = 'ONCE_AS
runWriteInStatelessSession(
q ->
q.createNativeQuery(sql2)
.addSynchronizedEntityClass(FileResource.class)
.setLockOptions(new LockOptions(LockMode.PESSIMISTIC_WRITE).setTimeOut(2000))
.executeUpdate());
return deletedCount;
Expand Down Expand Up @@ -606,7 +617,7 @@ and now() > lastalive + :timeout * interval '1 minute'
""";
return runWriteInStatelessSession(
q ->
q.createNativeQuery(sql)
nativeSynchronizedQuery(q, sql)
.setParameter("timeout", max(1, timeoutMinutes))
.executeUpdate());
}
Expand Down Expand Up @@ -637,7 +648,10 @@ public boolean tryRevertNow(@Nonnull UID jobId) {
and now() > jobconfiguration.lastalive + interval '1 minute'
""";
return runWriteInStatelessSession(
q -> q.createNativeQuery(sql).setParameter("id", jobId.getValue()).executeUpdate())
q ->
nativeSynchronizedQuery(q, sql)
.setParameter("id", jobId.getValue())
.executeUpdate())
> 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.hisp.dhis.cache.QueryCacheManager;
import org.hisp.dhis.category.Category;
import org.hisp.dhis.common.IdentifiableObjectUtils;
import org.hisp.dhis.common.Locale;
import org.hisp.dhis.common.UID;
Expand Down Expand Up @@ -742,8 +743,11 @@ WHERE dataelementcategoryid IN (:sourceCategoryIds)
ORDER BY userid, dataelementcategoryid
)
""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
// users_catdimensionconstraints is the User.catDimensionConstraints collection table.
// Collection regions are keyed by the collection's element entity, so Category is what
// reaches that region, not the owning User.
.addSynchronizedEntityClass(Category.class)
.setParameter("targetCategoryId", targetCategoryId)
.setParameter("sourceCategoryIds", sourceCategoryIds)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(5000))
Expand All @@ -759,8 +763,9 @@ public int deleteRemainingCatDimensionConstraints(Set<Long> sourceCategoryIds) {
DELETE FROM users_catdimensionconstraints
WHERE dataelementcategoryid IN (:sourceCategoryIds)
""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
// see updateCatDimensionConstraintsCategoryRefs
.addSynchronizedEntityClass(Category.class)
.setParameter("sourceCategoryIds", sourceCategoryIds)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(5000))
.executeUpdate();
Expand All @@ -780,8 +785,9 @@ AND userid IN (
WHERE dataelementcategoryid = :targetCategoryId
)
""";
return getSession()
.createNativeQuery(sql)
return nativeSynchronizedQuery(sql)
// see updateCatDimensionConstraintsCategoryRefs
.addSynchronizedEntityClass(Category.class)
.setParameter("targetCategoryId", targetCategoryId)
.setParameter("sourceCategoryIds", sourceCategoryIds)
.setLockOptions(new LockOptions(PESSIMISTIC_WRITE).setTimeOut(5000))
Expand Down
Loading
Loading