This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/master by this push:
new cca99eae9 CAY-2868 Regression: DefaultDbRowOpSorter shouldn't sort
update operations
cca99eae9 is described below
commit cca99eae99f290adb67c44fd9ae66565ff7ddfff
Author: Nikita Timofeev <[email protected]>
AuthorDate: Fri Aug 16 12:26:35 2024 +0300
CAY-2868 Regression: DefaultDbRowOpSorter shouldn't sort update operations
---
RELEASE-NOTES.txt | 1 +
.../flush/operation/DefaultDbRowOpSorter.java | 7 ++++---
.../access/flush/DefaultDbRowOpSorterTest.java | 24 ++++++++++++++++++++++
3 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 3a5031e99..19ed50585 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -126,3 +126,4 @@ CAY-2851 Replace Existing OneToOne From New Object
CAY-2853 Incorrect deletion of entities from flattened attributes
CAY-2854 Improve delete prevention detection of flattened attribute row
CAY-2866 DefaultDataDomainFlushAction breaks on circular relationship update
+CAY-2868 Regression: DefaultDbRowOpSorter shouldn't sort update operations
diff --git
a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/DefaultDbRowOpSorter.java
b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/DefaultDbRowOpSorter.java
index ed431719e..f02eb7eb8 100644
---
a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/DefaultDbRowOpSorter.java
+++
b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/DefaultDbRowOpSorter.java
@@ -64,7 +64,8 @@ public class DefaultDbRowOpSorter implements DbRowOpSorter {
for (int i = 0; i < sortedDbRows.size(); i++) {
DbRowOp row = sortedDbRows.get(i);
if (row.getEntity() != lastEntity) {
- if(lastEntity != null && sorter.isReflexive(lastEntity)) {
+ // we do not sort update operations
+ if(lastEntity != null && !(lastRow instanceof UpdateDbRowOp)
&& sorter.isReflexive(lastEntity)) {
ObjEntity objEntity =
resolver.getObjEntity(lastRow.getObject().getObjectId().getEntityName());
List<DbRowOp> reflexiveSublist =
sortedDbRows.subList(start, idx);
sorter.sortObjectsForEntity(objEntity, reflexiveSublist,
lastRow instanceof DeleteDbRowOp);
@@ -76,7 +77,7 @@ public class DefaultDbRowOpSorter implements DbRowOpSorter {
idx++;
}
// sort last chunk
- if(lastEntity != null && sorter.isReflexive(lastEntity)) {
+ if(lastEntity != null && !(lastRow instanceof UpdateDbRowOp) &&
sorter.isReflexive(lastEntity)) {
ObjEntity objEntity =
resolver.getObjEntity(lastRow.getObject().getObjectId().getEntityName());
List<DbRowOp> reflexiveSublist = sortedDbRows.subList(start, idx);
sorter.sortObjectsForEntity(objEntity, reflexiveSublist, lastRow
instanceof DeleteDbRowOp);
@@ -116,7 +117,7 @@ public class DefaultDbRowOpSorter implements DbRowOpSorter {
return result;
}
- // 2. sort by entity relations
+ // 2. sort by entity relations, we don't really need this for
updates, but do it for the stable result
result =
entitySorter.getDbEntityComparator().compare(left.getEntity(),
right.getEntity());
if(result != 0) {
// invert result for delete
diff --git
a/cayenne/src/test/java/org/apache/cayenne/access/flush/DefaultDbRowOpSorterTest.java
b/cayenne/src/test/java/org/apache/cayenne/access/flush/DefaultDbRowOpSorterTest.java
index b4bd0217b..8fbb3ddd4 100644
---
a/cayenne/src/test/java/org/apache/cayenne/access/flush/DefaultDbRowOpSorterTest.java
+++
b/cayenne/src/test/java/org/apache/cayenne/access/flush/DefaultDbRowOpSorterTest.java
@@ -192,8 +192,32 @@ public class DefaultDbRowOpSorterTest {
List<DbRowOp> sorted = sorter.sort(rows);
assertEquals(expected, sorted); // no actual sorting is done
+ verify(entitySorter, times(3)).getDbEntityComparator();
verify(entitySorter) // should call entity sorter
.sortObjectsForEntity(isNull(), any(List.class), eq(false));
+ verifyNoMoreInteractions(entitySorter);
+ }
+
+ @Test
+ public void sortReflexiveUpdates() {
+ ObjectId id1 = ObjectId.of("reflexive", "id", 1);
+ ObjectId id2 = ObjectId.of("reflexive", "id", 2);
+ ObjectId id3 = ObjectId.of("reflexive", "id", 3);
+ ObjectId id4 = ObjectId.of("reflexive", "id", 4);
+
+ DbEntity reflexive = mockEntity("reflexive");
+ DbRowOp op1 = new UpdateDbRowOp(mockObject(id1), reflexive, id1);
+ DbRowOp op2 = new UpdateDbRowOp(mockObject(id2), reflexive, id2);
+ DbRowOp op3 = new UpdateDbRowOp(mockObject(id3), reflexive, id3);
+ DbRowOp op4 = new UpdateDbRowOp(mockObject(id4), reflexive, id4);
+
+ List<DbRowOp> rows = Arrays.asList(op1, op2, op3, op4);
+ List<DbRowOp> expected = Arrays.asList(op1, op2, op3, op4);
+
+ List<DbRowOp> sorted = sorter.sort(rows);
+ assertEquals(expected, sorted); // no actual sorting is done
+ verify(entitySorter, times(3)).getDbEntityComparator();
+ verifyNoMoreInteractions(entitySorter); // shouldn't call entity sorter
}
private Persistent mockObject(ObjectId id) {