From 6e51039369f53646c05304d05cc66fb62f1361ac Mon Sep 17 00:00:00 2001 From: Enrico Date: Tue, 12 May 2026 11:08:23 +0200 Subject: [PATCH 1/3] chore: Extract FileResource assignment update [DHIS2-21378] --- .../org/hisp/dhis/fileresource/FileResourceStore.java | 8 ++++++++ .../hibernate/HibernateFileResourceStore.java | 10 ++++++++++ .../TrackedEntityProgramAttributeFileResourceTest.java | 2 ++ .../tracker/imports/validation/TeTaValidationTest.java | 4 ++++ .../bundle/persister/AbstractTrackerPersister.java | 10 +++++++--- .../imports/bundle/persister/EnrollmentPersister.java | 4 +++- .../bundle/persister/RelationshipPersister.java | 8 ++++++-- .../imports/bundle/persister/SingleEventPersister.java | 8 ++++++-- .../bundle/persister/TrackedEntityPersister.java | 8 ++++++-- .../bundle/persister/TrackerEventPersister.java | 8 ++++++-- 10 files changed, 58 insertions(+), 12 deletions(-) diff --git a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/fileresource/FileResourceStore.java b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/fileresource/FileResourceStore.java index 3e8d9a1aa98e..e06049eff727 100644 --- a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/fileresource/FileResourceStore.java +++ b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/fileresource/FileResourceStore.java @@ -120,4 +120,12 @@ Optional findByUidAndDomain( List getUnassignedPassedGracePeriod( Set domainsToDeleteWhenUnassigned, DateTime minus); + + /** + * Updates the assignment state and owner of the file resource with the given uid via a single + * JDBC UPDATE. Bypasses the Hibernate persistence context, so {@link + * org.hisp.dhis.artemis.audit.listener.AbstractHibernateListener Hibernate audit listeners} do + * not fire. No-op if no file resource with that uid exists. + */ + void updateAssignment(@Nonnull String uid, boolean assigned, @Nonnull String fileResourceOwner); } diff --git a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/fileresource/hibernate/HibernateFileResourceStore.java b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/fileresource/hibernate/HibernateFileResourceStore.java index ac2aed532f31..d9bb198d8d58 100644 --- a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/fileresource/hibernate/HibernateFileResourceStore.java +++ b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/fileresource/hibernate/HibernateFileResourceStore.java @@ -212,6 +212,16 @@ and fr.uid not in (select uid from jobconfiguration where schedulingtype = 'ONCE return nativeSynchronizedTypedQuery(sql).list(); } + @Override + public void updateAssignment( + @Nonnull String uid, boolean assigned, @Nonnull String fileResourceOwner) { + jdbcTemplate.update( + "update fileresource set isassigned = ?, fileresourceowner = ?, lastupdated = now() where uid = ?", + assigned, + fileResourceOwner, + uid); + } + @Override public List getUnassignedPassedGracePeriod( Set domainsToDeleteWhenUnassigned, DateTime gracePeriod) { diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/bundle/TrackedEntityProgramAttributeFileResourceTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/bundle/TrackedEntityProgramAttributeFileResourceTest.java index 0948d6b78e33..1a187e769d9c 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/bundle/TrackedEntityProgramAttributeFileResourceTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/bundle/TrackedEntityProgramAttributeFileResourceTest.java @@ -97,6 +97,8 @@ void testTrackedEntityProgramAttributeFileResourceValue() throws IOException { List attributeValues = trackedEntityAttributeValueService.getTrackedEntityAttributeValues(trackedEntity); assertEquals(5, attributeValues.size()); + manager.clear(); + manager.flush(); fileResource = fileResourceService.getFileResource(fileResource.getUid()); assertTrue(fileResource.isAssigned()); } diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/validation/TeTaValidationTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/validation/TeTaValidationTest.java index 8c1e69a59029..64f90cb84a55 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/validation/TeTaValidationTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/validation/TeTaValidationTest.java @@ -108,6 +108,8 @@ void testTrackedEntityProgramAttributeFileResourceValue() throws IOException { List attributeValues = trackedEntityAttributeValueService.getTrackedEntityAttributeValues(trackedEntity); assertEquals(1, attributeValues.size()); + manager.clear(); + manager.flush(); fileResource = fileResourceService.getFileResource(fileResource.getUid()); assertTrue(fileResource.isAssigned()); } @@ -137,6 +139,8 @@ void testFileAlreadyAssign() throws IOException { List attributeValues = trackedEntityAttributeValueService.getTrackedEntityAttributeValues(trackedEntity); assertEquals(1, attributeValues.size()); + manager.clear(); + manager.flush(); fileResource = fileResourceService.getFileResource(fileResource.getUid()); assertTrue(fileResource.isAssigned()); trackerObjects = diff --git a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/AbstractTrackerPersister.java b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/AbstractTrackerPersister.java index 25712dbdbc42..fca2f2a38840 100644 --- a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/AbstractTrackerPersister.java +++ b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/AbstractTrackerPersister.java @@ -61,6 +61,7 @@ import org.hisp.dhis.common.UID; import org.hisp.dhis.common.ValueType; import org.hisp.dhis.fileresource.FileResource; +import org.hisp.dhis.fileresource.FileResourceStore; import org.hisp.dhis.program.notification.ProgramNotificationTemplate; import org.hisp.dhis.reservedvalue.ReservedValueService; import org.hisp.dhis.trackedentity.TrackedEntityAttribute; @@ -99,6 +100,8 @@ public abstract class AbstractTrackerPersister { - public RelationshipPersister(ReservedValueService reservedValueService, DataSource dataSource) { - super(reservedValueService, dataSource); + public RelationshipPersister( + ReservedValueService reservedValueService, + DataSource dataSource, + FileResourceStore fileResourceStore) { + super(reservedValueService, dataSource, fileResourceStore); } @Override diff --git a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/SingleEventPersister.java b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/SingleEventPersister.java index db1917d65a31..8ff91940277c 100644 --- a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/SingleEventPersister.java +++ b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/SingleEventPersister.java @@ -51,6 +51,7 @@ import org.hisp.dhis.dataelement.DataElement; import org.hisp.dhis.event.EventStatus; import org.hisp.dhis.eventdatavalue.EventDataValue; +import org.hisp.dhis.fileresource.FileResourceStore; import org.hisp.dhis.program.Program; import org.hisp.dhis.program.UserInfoSnapshot; import org.hisp.dhis.program.notification.NotificationTrigger; @@ -74,8 +75,11 @@ public class SingleEventPersister extends AbstractTrackerPersister< org.hisp.dhis.tracker.imports.domain.SingleEvent, SingleEvent> { - public SingleEventPersister(ReservedValueService reservedValueService, DataSource dataSource) { - super(reservedValueService, dataSource); + public SingleEventPersister( + ReservedValueService reservedValueService, + DataSource dataSource, + FileResourceStore fileResourceStore) { + super(reservedValueService, dataSource, fileResourceStore); } @Override diff --git a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/TrackedEntityPersister.java b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/TrackedEntityPersister.java index 18babf87bf85..b64a201c52aa 100644 --- a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/TrackedEntityPersister.java +++ b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/TrackedEntityPersister.java @@ -34,6 +34,7 @@ import java.util.Set; import javax.sql.DataSource; import org.hisp.dhis.common.UID; +import org.hisp.dhis.fileresource.FileResourceStore; import org.hisp.dhis.reservedvalue.ReservedValueService; import org.hisp.dhis.tracker.TrackerType; import org.hisp.dhis.tracker.imports.bundle.TrackerBundle; @@ -51,8 +52,11 @@ public class TrackedEntityPersister extends AbstractTrackerPersister< org.hisp.dhis.tracker.imports.domain.TrackedEntity, TrackedEntity> { - public TrackedEntityPersister(ReservedValueService reservedValueService, DataSource dataSource) { - super(reservedValueService, dataSource); + public TrackedEntityPersister( + ReservedValueService reservedValueService, + DataSource dataSource, + FileResourceStore fileResourceStore) { + super(reservedValueService, dataSource, fileResourceStore); } @Override diff --git a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/TrackerEventPersister.java b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/TrackerEventPersister.java index 4394bc349a11..25b83ae2aea5 100644 --- a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/TrackerEventPersister.java +++ b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/TrackerEventPersister.java @@ -52,6 +52,7 @@ import org.hisp.dhis.dataelement.DataElement; import org.hisp.dhis.event.EventStatus; import org.hisp.dhis.eventdatavalue.EventDataValue; +import org.hisp.dhis.fileresource.FileResourceStore; import org.hisp.dhis.program.Program; import org.hisp.dhis.program.UserInfoSnapshot; import org.hisp.dhis.program.notification.NotificationTrigger; @@ -75,8 +76,11 @@ public class TrackerEventPersister extends AbstractTrackerPersister< org.hisp.dhis.tracker.imports.domain.TrackerEvent, TrackerEvent> { - public TrackerEventPersister(ReservedValueService reservedValueService, DataSource dataSource) { - super(reservedValueService, dataSource); + public TrackerEventPersister( + ReservedValueService reservedValueService, + DataSource dataSource, + FileResourceStore fileResourceStore) { + super(reservedValueService, dataSource, fileResourceStore); } @Override From c0d3bb8116754788825805c64b931e5d53fec040 Mon Sep 17 00:00:00 2001 From: Enrico Date: Fri, 15 May 2026 13:32:35 +0200 Subject: [PATCH 2/3] Code review fixes --- .../java/org/hisp/dhis/fileresource/FileResourceStore.java | 4 +--- .../imports/bundle/persister/AbstractTrackerPersister.java | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/fileresource/FileResourceStore.java b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/fileresource/FileResourceStore.java index e06049eff727..1487cd1e4ac9 100644 --- a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/fileresource/FileResourceStore.java +++ b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/fileresource/FileResourceStore.java @@ -123,9 +123,7 @@ List getUnassignedPassedGracePeriod( /** * Updates the assignment state and owner of the file resource with the given uid via a single - * JDBC UPDATE. Bypasses the Hibernate persistence context, so {@link - * org.hisp.dhis.artemis.audit.listener.AbstractHibernateListener Hibernate audit listeners} do - * not fire. No-op if no file resource with that uid exists. + * JDBC UPDATE. No-op if no file resource with that uid exists. */ void updateAssignment(@Nonnull String uid, boolean assigned, @Nonnull String fileResourceOwner); } diff --git a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/AbstractTrackerPersister.java b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/AbstractTrackerPersister.java index fca2f2a38840..3d5734640dc7 100644 --- a/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/AbstractTrackerPersister.java +++ b/dhis-2/dhis-tracker/src/main/java/org/hisp/dhis/tracker/imports/bundle/persister/AbstractTrackerPersister.java @@ -368,9 +368,6 @@ private void assignFileResource( return; } - // Direct JDBC update — bypasses the Hibernate persistence context so the entity is not - // dirty-marked and PostUpdateAuditListener does not fire. The in-memory copy in the preheat - // is intentionally left as-is; nothing reads it back later in this import. fileResourceStore.updateAssignment(fileResource.getUid(), isAssign, fileResourceOwner); } From 7bf5208dfe2df7f81177458ae1cbe07000409417 Mon Sep 17 00:00:00 2001 From: Enrico Date: Thu, 21 May 2026 14:53:03 +0200 Subject: [PATCH 3/3] Code review fixes --- .../bundle/TrackedEntityProgramAttributeFileResourceTest.java | 1 - .../dhis/tracker/imports/validation/TeTaValidationTest.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/bundle/TrackedEntityProgramAttributeFileResourceTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/bundle/TrackedEntityProgramAttributeFileResourceTest.java index 1a187e769d9c..a55e4fe945f2 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/bundle/TrackedEntityProgramAttributeFileResourceTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/bundle/TrackedEntityProgramAttributeFileResourceTest.java @@ -98,7 +98,6 @@ void testTrackedEntityProgramAttributeFileResourceValue() throws IOException { trackedEntityAttributeValueService.getTrackedEntityAttributeValues(trackedEntity); assertEquals(5, attributeValues.size()); manager.clear(); - manager.flush(); fileResource = fileResourceService.getFileResource(fileResource.getUid()); assertTrue(fileResource.isAssigned()); } diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/validation/TeTaValidationTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/validation/TeTaValidationTest.java index 64f90cb84a55..5507f8732c8b 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/validation/TeTaValidationTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/imports/validation/TeTaValidationTest.java @@ -109,7 +109,6 @@ void testTrackedEntityProgramAttributeFileResourceValue() throws IOException { trackedEntityAttributeValueService.getTrackedEntityAttributeValues(trackedEntity); assertEquals(1, attributeValues.size()); manager.clear(); - manager.flush(); fileResource = fileResourceService.getFileResource(fileResource.getUid()); assertTrue(fileResource.isAssigned()); } @@ -140,7 +139,6 @@ void testFileAlreadyAssign() throws IOException { trackedEntityAttributeValueService.getTrackedEntityAttributeValues(trackedEntity); assertEquals(1, attributeValues.size()); manager.clear(); - manager.flush(); fileResource = fileResourceService.getFileResource(fileResource.getUid()); assertTrue(fileResource.isAssigned()); trackerObjects =