From 83d30e8779270b25c24beab79f8de951e4e02a9b Mon Sep 17 00:00:00 2001 From: Ujjawal Prabhat Date: Tue, 25 Aug 2026 23:48:31 +0800 Subject: [PATCH 1/2] O3-5763: Fetch queue entry associations lazily QueueEntry and Queue left their *ToOne associations at the JPA default of EAGER, so reading one queue entry pulled every association's own eager graph in a single 30-join statement. On a fresh database, which ships zero-row statistics, that statement does not finish; lazily it returns in about a second. Also excluded from Lombok's equals, hashCode and toString, which would otherwise re-initialise the proxies. --- .../org/openmrs/module/queue/model/Queue.java | 12 ++++--- .../module/queue/model/QueueEntry.java | 31 ++++++++++++++----- .../openmrs/module/queue/model/QueueRoom.java | 4 ++- .../module/queue/model/RoomProviderMap.java | 7 +++-- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/queue/model/Queue.java b/api/src/main/java/org/openmrs/module/queue/model/Queue.java index 6dcc0631..b59dd25a 100644 --- a/api/src/main/java/org/openmrs/module/queue/model/Queue.java +++ b/api/src/main/java/org/openmrs/module/queue/model/Queue.java @@ -49,19 +49,23 @@ public class Queue extends BaseChangeableOpenmrsMetadata { @Column(name = "queue_id") private Integer queueId; - @ManyToOne + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "location_id", nullable = false) private Location location; - @ManyToOne + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "service", referencedColumnName = "concept_id", nullable = false) private Concept service; - @ManyToOne + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "priority_concept_set", referencedColumnName = "concept_id") private Concept priorityConceptSet; - @ManyToOne + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "status_concept_set", referencedColumnName = "concept_id") private Concept statusConceptSet; diff --git a/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java b/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java index a2ab33be..97b7df6a 100644 --- a/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java +++ b/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java @@ -11,6 +11,7 @@ import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -50,26 +51,35 @@ public class QueueEntry extends BaseChangeableOpenmrsData { private Integer queueEntryId; @ToString.Exclude - @ManyToOne + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "queue_id", nullable = false) private Queue queue; - @ManyToOne + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "patient_id", nullable = false) private Patient patient; - @ManyToOne + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "visit_id") private Visit visit; - @ManyToOne + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "priority", referencedColumnName = "concept_id", nullable = false) private Concept priority; @Column(name = "priority_comment") private String priorityComment; - @ManyToOne + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "status", referencedColumnName = "concept_id", nullable = false) private Concept status; @@ -78,18 +88,23 @@ public class QueueEntry extends BaseChangeableOpenmrsData { private Double sortWeight = 0.0; //The Location the patient is waiting for, if any. - @ManyToOne + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "location_waiting_for", referencedColumnName = "location_id") private Location locationWaitingFor; //The Provider the patient is waiting for, if any. - @ManyToOne + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "provider_waiting_for", referencedColumnName = "provider_id") private Provider providerWaitingFor; //The queue the patient is coming from, if any. @ToString.Exclude - @OneToOne + @EqualsAndHashCode.Exclude + @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "queue_coming_from", referencedColumnName = "queue_id") private Queue queueComingFrom; diff --git a/api/src/main/java/org/openmrs/module/queue/model/QueueRoom.java b/api/src/main/java/org/openmrs/module/queue/model/QueueRoom.java index 8a837de4..28889cc8 100644 --- a/api/src/main/java/org/openmrs/module/queue/model/QueueRoom.java +++ b/api/src/main/java/org/openmrs/module/queue/model/QueueRoom.java @@ -11,6 +11,7 @@ import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -39,7 +40,8 @@ public class QueueRoom extends BaseChangeableOpenmrsMetadata { @Column(name = "queue_room_id") private Integer queueRoom; - @ManyToOne + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "queue_id", nullable = false) private Queue queue; diff --git a/api/src/main/java/org/openmrs/module/queue/model/RoomProviderMap.java b/api/src/main/java/org/openmrs/module/queue/model/RoomProviderMap.java index f6f65c1f..f167c1eb 100644 --- a/api/src/main/java/org/openmrs/module/queue/model/RoomProviderMap.java +++ b/api/src/main/java/org/openmrs/module/queue/model/RoomProviderMap.java @@ -11,6 +11,7 @@ import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -40,11 +41,13 @@ public class RoomProviderMap extends BaseOpenmrsData { @Column(name = "room_provider_map_id") private Integer roomProviderMapId; - @ManyToOne + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "queue_room_id", nullable = false) private QueueRoom queueRoom; - @ManyToOne + @EqualsAndHashCode.Exclude + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "provider_id", nullable = false) private Provider provider; From 36db0f7e5fa6675857b02874e1d53fa4969d10d7 Mon Sep 17 00:00:00 2001 From: Ujjawal Prabhat Date: Wed, 26 Aug 2026 00:49:51 +0800 Subject: [PATCH 2/2] O3-5763: Inherit equals and hashCode rather than generating them Address review feedback: BaseOpenmrsObject already implements both in terms of the UUID, so the entities don't need Lombok's generated versions. That also removes the need to exclude each association from them. --- .../java/org/openmrs/module/queue/model/Queue.java | 6 ------ .../org/openmrs/module/queue/model/QueueEntry.java | 10 ---------- .../java/org/openmrs/module/queue/model/QueueRoom.java | 3 --- .../openmrs/module/queue/model/RoomProviderMap.java | 4 ---- 4 files changed, 23 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/queue/model/Queue.java b/api/src/main/java/org/openmrs/module/queue/model/Queue.java index b59dd25a..aab8f00d 100644 --- a/api/src/main/java/org/openmrs/module/queue/model/Queue.java +++ b/api/src/main/java/org/openmrs/module/queue/model/Queue.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.stream.Collectors; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -34,7 +33,6 @@ import org.openmrs.Concept; import org.openmrs.Location; -@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @Setter @Getter @@ -49,22 +47,18 @@ public class Queue extends BaseChangeableOpenmrsMetadata { @Column(name = "queue_id") private Integer queueId; - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "location_id", nullable = false) private Location location; - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "service", referencedColumnName = "concept_id", nullable = false) private Concept service; - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "priority_concept_set", referencedColumnName = "concept_id") private Concept priorityConceptSet; - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "status_concept_set", referencedColumnName = "concept_id") private Concept statusConceptSet; diff --git a/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java b/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java index 97b7df6a..1d721c3f 100644 --- a/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java +++ b/api/src/main/java/org/openmrs/module/queue/model/QueueEntry.java @@ -22,7 +22,6 @@ import java.util.Date; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -34,7 +33,6 @@ import org.openmrs.Provider; import org.openmrs.Visit; -@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @Setter @Getter @@ -51,25 +49,21 @@ public class QueueEntry extends BaseChangeableOpenmrsData { private Integer queueEntryId; @ToString.Exclude - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "queue_id", nullable = false) private Queue queue; @ToString.Exclude - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "patient_id", nullable = false) private Patient patient; @ToString.Exclude - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "visit_id") private Visit visit; @ToString.Exclude - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "priority", referencedColumnName = "concept_id", nullable = false) private Concept priority; @@ -78,7 +72,6 @@ public class QueueEntry extends BaseChangeableOpenmrsData { private String priorityComment; @ToString.Exclude - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "status", referencedColumnName = "concept_id", nullable = false) private Concept status; @@ -89,21 +82,18 @@ public class QueueEntry extends BaseChangeableOpenmrsData { //The Location the patient is waiting for, if any. @ToString.Exclude - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "location_waiting_for", referencedColumnName = "location_id") private Location locationWaitingFor; //The Provider the patient is waiting for, if any. @ToString.Exclude - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "provider_waiting_for", referencedColumnName = "provider_id") private Provider providerWaitingFor; //The queue the patient is coming from, if any. @ToString.Exclude - @EqualsAndHashCode.Exclude @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "queue_coming_from", referencedColumnName = "queue_id") private Queue queueComingFrom; diff --git a/api/src/main/java/org/openmrs/module/queue/model/QueueRoom.java b/api/src/main/java/org/openmrs/module/queue/model/QueueRoom.java index 28889cc8..ea58bfb6 100644 --- a/api/src/main/java/org/openmrs/module/queue/model/QueueRoom.java +++ b/api/src/main/java/org/openmrs/module/queue/model/QueueRoom.java @@ -19,13 +19,11 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.openmrs.BaseChangeableOpenmrsMetadata; -@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @Setter @Getter @@ -40,7 +38,6 @@ public class QueueRoom extends BaseChangeableOpenmrsMetadata { @Column(name = "queue_room_id") private Integer queueRoom; - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "queue_id", nullable = false) private Queue queue; diff --git a/api/src/main/java/org/openmrs/module/queue/model/RoomProviderMap.java b/api/src/main/java/org/openmrs/module/queue/model/RoomProviderMap.java index f167c1eb..ef72c210 100644 --- a/api/src/main/java/org/openmrs/module/queue/model/RoomProviderMap.java +++ b/api/src/main/java/org/openmrs/module/queue/model/RoomProviderMap.java @@ -19,14 +19,12 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.openmrs.BaseOpenmrsData; import org.openmrs.Provider; -@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @Setter @Getter @@ -41,12 +39,10 @@ public class RoomProviderMap extends BaseOpenmrsData { @Column(name = "room_provider_map_id") private Integer roomProviderMapId; - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "queue_room_id", nullable = false) private QueueRoom queueRoom; - @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "provider_id", nullable = false) private Provider provider;