You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2026/06/11 23:08:00 UTC

(cayenne) 04/04: CAY-2959 Modeler: DbRelationship dialog "Cancel" does not cancel

This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch past-M2
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit 5f78e6dbcf524ec3d6a592f4b6096c1bf627d853
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Thu Jun 11 19:05:42 2026 -0400

    CAY-2959 Modeler: DbRelationship dialog "Cancel" does not cancel
    
    bonus points: do notdirty the project of no changes occured
---
 .../ui/dbrelationship/DbRelationshipDialog.java    | 55 ++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
index 8a1d5184c..0d83b75b8 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
@@ -317,6 +317,11 @@ public class DbRelationshipDialog extends ProjectDialog {
     private void save() {
         stopEditing();
 
+        // "Done" with no edits must behave like "Cancel" - no mutation, no events, no dirty flag
+        if (!create && !hasChanges()) {
+            return;
+        }
+
         handleNameUpdate(relationship, name.getText().trim());
 
         // the single place where the dialog editing state is written to the relationship
@@ -394,6 +399,56 @@ public class DbRelationshipDialog extends ProjectDialog {
         }
     }
 
+    /**
+     * Compares the dialog widget state against the untouched relationship, covering every input that
+     * {@link #save()} would write. Must be called before any mutation.
+     */
+    private boolean hasChanges() {
+        if (!Objects.equals(relationship.getName(), name.getText().trim())) {
+            return true;
+        }
+        if (!Objects.equals(relationship.getTargetEntityName(), currentTarget != null ? currentTarget.getName() : null)) {
+            return true;
+        }
+        if (relationship.isToMany() != toMany.isSelected()) {
+            return true;
+        }
+        if (relationship.isToDependentPK() != toDepPk.isSelected()) {
+            return true;
+        }
+        if (unsetReverseDepPk && reverseRelationship != null && reverseRelationship.isToDependentPK()) {
+            return true;
+        }
+        if (reverseRelationship != null
+                && !Objects.equals(reverseRelationship.getName(), reverseName.getText().trim())) {
+            return true;
+        }
+        if (joinsChanged()) {
+            return true;
+        }
+
+        String oldComment = ObjectInfo.getFromMetaData(app.getMetaData(), relationship, ObjectInfo.COMMENT);
+        return !Objects.equals(oldComment != null ? oldComment : "", comment.getText());
+    }
+
+    /**
+     * Compares the join table rows against the relationship's joins, ignoring blank rows (the ones
+     * {@link DbJoinTableModel#commit()} drops) and row order, so that merely sorting the table by a column
+     * doesn't count as a change.
+     */
+    private boolean joinsChanged() {
+        List<String> edited = ((DbJoinTableModel) table.getModel()).getObjectList().stream()
+                .filter(j -> j.getSourceName() != null || j.getTargetName() != null)
+                .map(j -> j.getSourceName() + "→" + j.getTargetName())
+                .sorted()
+                .toList();
+        List<String> existing = relationship.getJoins().stream()
+                .map(j -> j.getSourceName() + "→" + j.getTargetName())
+                .sorted()
+                .toList();
+        return !edited.equals(existing);
+    }
+
     private void handleNameUpdate(DbRelationship rel, String userInputName) {
         if (Objects.equals(rel.getName(), userInputName)) {
             return;