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

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

commit 9252154d367f72591a6373694d16d75d86f3e7ec
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sat Jul 11 16:36:28 2026 -0400

    CAY-2976 Exception creating a relationship for an Incomplete ObjEntity
---
 RELEASE-NOTES.txt                                  |  1 +
 .../ui/action/CreateRelationshipAction.java        |  8 +++---
 .../objentity/properties/ObjRelationshipPanel.java |  6 ++++-
 .../relinfo/ObjRelationshipInfoDialog.java         | 30 +++++++++++++---------
 4 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index c03ea2ff2..02a53f58a 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -39,6 +39,7 @@ CAY-2966 "comment" field is lost when upgrading from v10 to 
v12
 CAY-2967 SQLTemplate/SQLSelect broken pagination
 CAY-2968 Vertical Inheritance: INSERT instead of UPDATE after updating 
flattened attribute
 CAY-2973 Exception trying to copy/paste a callback
+CAY-2976 Exception creating a relationship for an Incomplete ObjEntity
 
 ----------------------------------
 Release: 5.0-M2
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/CreateRelationshipAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/CreateRelationshipAction.java
index 41fb7983e..4d954dd25 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/CreateRelationshipAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/action/CreateRelationshipAction.java
@@ -86,9 +86,11 @@ public class CreateRelationshipAction extends AppAction {
         ObjEntity objEnt = getProjectSession().getSelectedObjEntity();
         if (objEnt != null) {
 
-            new ObjRelationshipInfoDialog(getProjectSession(), app.getFrame())
-                    .createRelationship(objEnt)
-                    .open();
+            if (ObjRelationshipInfoDialog.canMap(objEnt, app.getFrame())) {
+                new ObjRelationshipInfoDialog(getProjectSession(), 
app.getFrame())
+                        .createRelationship(objEnt)
+                        .open();
+            }
 
         } else {
             DbEntity dbEnt = getProjectSession().getSelectedDbEntity();
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
index 368379df2..d55768ef4 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
@@ -377,8 +377,12 @@ public class ObjRelationshipPanel extends ProjectPanel 
implements ObjEntityDispl
         }
 
         ObjRelationshipTableModel model = (ObjRelationshipTableModel) 
table.getModel();
+        ObjRelationship relationship = model.getRelationship(row);
+        if (!ObjRelationshipInfoDialog.canMap(relationship.getSourceEntity(), 
app.getFrame())) {
+            return;
+        }
         new ObjRelationshipInfoDialog(session, app.getFrame())
-                .modifyRelationship(model.getRelationship(row))
+                .modifyRelationship(relationship)
                 .open();
 
         // This is required for a table to be updated properly
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/relinfo/ObjRelationshipInfoDialog.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/relinfo/ObjRelationshipInfoDialog.java
index 3b0d9f09f..9c318c6b1 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/relinfo/ObjRelationshipInfoDialog.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/relinfo/ObjRelationshipInfoDialog.java
@@ -21,7 +21,6 @@ package 
org.apache.cayenne.modeler.ui.project.editor.objentity.relinfo;
 import com.jgoodies.forms.builder.PanelBuilder;
 import com.jgoodies.forms.layout.CellConstraints;
 import com.jgoodies.forms.layout.FormLayout;
-import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.dbsync.naming.NameBuilder;
 import org.apache.cayenne.map.DbEntity;
@@ -151,10 +150,6 @@ public class ObjRelationshipInfoDialog extends 
ProjectDialog implements TreeSele
         this.relationship = rel;
         this.undo = new ObjRelationshipUndoableEdit(session, rel);
 
-        // current limitation is that an ObjRelationship must have source
-        // and target entities present, with DbEntities chosen.
-        validateCanMap();
-
         initFromModel();
         initBindings();
         return this;
@@ -587,17 +582,28 @@ public class ObjRelationshipInfoDialog extends 
ProjectDialog implements TreeSele
     }
 
     /**
-     * Checks if the entity can be edited with this inspector.
+     * Checks whether the given source entity can be mapped with this 
inspector, showing an
+     * informative message and returning false if not. Callers must use this 
to decide whether to
+     * open the inspector at all — the dialog assumes a mappable source entity.
      * NOTE: As of CAY-1077, the inspector can be opened even with no target 
entity set.
      */
-    private void validateCanMap() {
-        if (relationship.getSourceEntity() == null) {
-            throw new CayenneRuntimeException("Can't map relationship without 
source entity.");
+    public static boolean canMap(ObjEntity source, Window owner) {
+        if (source == null) {
+            showCannotMapMessage(owner, "This relationship has no source 
ObjEntity, so it can't be mapped.");
+            return false;
         }
-        if (getStartEntity() == null) {
-            JOptionPane.showMessageDialog(this, "Can't map relationship 
without source DbEntity. Set source DbEntity.");
-            throw new CayenneRuntimeException("Can't map relationship without 
source DbEntity.");
+        if (source.getDbEntity() == null) {
+            String message = """
+                    "ObjEntity '%s' is not mapped to a DbEntity. Set either 
DbEntity or super ObjEntity on the \
+                    "ObjEntity" tab before mapping 
relationships.""".formatted(source.getName());
+            showCannotMapMessage(owner, message);
+            return false;
         }
+        return true;
+    }
+
+    private static void showCannotMapMessage(Window owner, String message) {
+        JOptionPane.showMessageDialog(owner, message, "Can't Map 
Relationship", JOptionPane.WARNING_MESSAGE);
     }
 
     private DbEntity getStartEntity() {

Reply via email to