Bug 561664: JoinColumn with same name and referencedColumnName throws exception

Signed-off-by: Will Dazey <dazeydev.3@gmail.com>
diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/mappings/OneToOneMapping.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/mappings/OneToOneMapping.java
index 9fbb370..1a00c37 100644
--- a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/mappings/OneToOneMapping.java
+++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/mappings/OneToOneMapping.java
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 1998, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020 IBM Corporation. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -448,56 +449,59 @@
             clone.setForeignKeyFields(org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(getForeignKeyFields().size()));
             clone.setSourceToTargetKeyFields(new HashMap(getSourceToTargetKeyFields().size()));
             clone.setTargetToSourceKeyFields(new HashMap(getTargetToSourceKeyFields().size()));
-            Hashtable setOfFields = new Hashtable(getTargetToSourceKeyFields().size());
 
-            //clone foreign keys and save the clones in a set
-            for (Enumeration enumtr = getForeignKeyFields().elements(); enumtr.hasMoreElements();) {
-                DatabaseField field = (DatabaseField)enumtr.nextElement();
+            // DatabaseField overrides equals, so we need to use an IdentifyHashMap for this implementation
+            // to make sure we are using the object references to lookup clone references
+            AbstractMap<DatabaseField, DatabaseField> fieldToCloneMap = new IdentityHashMap<DatabaseField, DatabaseField>(getTargetToSourceKeyFields().size());
+
+            //clone foreign keys and save the clones in a lookup table
+            for (Enumeration<DatabaseField> enumtr = getForeignKeyFields().elements(); enumtr.hasMoreElements();) {
+                DatabaseField field = enumtr.nextElement();
                 DatabaseField fieldClone = field.clone();
-                setOfFields.put(field, fieldClone);
+                fieldToCloneMap.put(field, fieldClone);
                 clone.getForeignKeyFields().addElement(fieldClone);
             }
 
-            //get clones from set for source hashtable.  If they do not exist, create a new one.
-            for (Iterator sourceEnum = getSourceToTargetKeyFields().keySet().iterator();
+            // lookup references in the map to get the associated clone reference. If it doesn't exist, create a new one.
+            for (Iterator<DatabaseField> sourceEnum = getSourceToTargetKeyFields().keySet().iterator();
                      sourceEnum.hasNext();) {
-                DatabaseField sourceField = (DatabaseField)sourceEnum.next();
+                DatabaseField sourceField = sourceEnum.next();
                 DatabaseField targetField = getSourceToTargetKeyFields().get(sourceField);
 
                 DatabaseField targetClone;
                 DatabaseField sourceClone;
 
-                targetClone = (DatabaseField)setOfFields.get(targetField);
+                targetClone = fieldToCloneMap.get(targetField);
                 if (targetClone == null) {
                     targetClone = targetField.clone();
-                    setOfFields.put(targetField, targetClone);
+                    fieldToCloneMap.put(targetField, targetClone);
                 }
-                sourceClone = (DatabaseField)setOfFields.get(sourceField);
+                sourceClone = fieldToCloneMap.get(sourceField);
                 if (sourceClone == null) {
                     sourceClone = sourceField.clone();
-                    setOfFields.put(sourceField, sourceClone);
+                    fieldToCloneMap.put(sourceField, sourceClone);
                 }
                 clone.getSourceToTargetKeyFields().put(sourceClone, targetClone);
             }
 
-            //get clones from set for target hashtable.  If they do not exist, create a new one.
-            for (Iterator targetEnum = getTargetToSourceKeyFields().keySet().iterator();
+            // lookup references in the map to get the associated clone reference. If it doesn't exist, create a new one.
+            for (Iterator<DatabaseField> targetEnum = getTargetToSourceKeyFields().keySet().iterator();
                      targetEnum.hasNext();) {
-                DatabaseField targetField = (DatabaseField)targetEnum.next();
+                DatabaseField targetField = targetEnum.next();
                 DatabaseField sourceField = getTargetToSourceKeyFields().get(targetField);
 
                 DatabaseField targetClone;
                 DatabaseField sourceClone;
 
-                targetClone = (DatabaseField)setOfFields.get(targetField);
+                targetClone = fieldToCloneMap.get(targetField);
                 if (targetClone == null) {
                     targetClone = targetField.clone();
-                    setOfFields.put(targetField, targetClone);
+                    fieldToCloneMap.put(targetField, targetClone);
                 }
-                sourceClone = (DatabaseField)setOfFields.get(sourceField);
+                sourceClone = fieldToCloneMap.get(sourceField);
                 if (sourceClone == null) {
                     sourceClone = sourceField.clone();
-                    setOfFields.put(sourceField, sourceClone);
+                    fieldToCloneMap.put(sourceField, sourceClone);
                 }
                 clone.getTargetToSourceKeyFields().put(targetClone, sourceClone);
             }
diff --git a/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/TestAggregateObjectMappings.java b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/TestAggregateObjectMappings.java
index 1594a06..159fdbd 100644
--- a/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/TestAggregateObjectMappings.java
+++ b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/TestAggregateObjectMappings.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2019 IBM Corporation. All rights reserved.
+ * Copyright (c) 2019, 2020 IBM Corporation. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -25,6 +25,9 @@
 import org.eclipse.persistence.jpa.test.framework.DDLGen;
 import org.eclipse.persistence.jpa.test.framework.Emf;
 import org.eclipse.persistence.jpa.test.framework.EmfRunner;
+import org.eclipse.persistence.jpa.test.mapping.model.BaseChild;
+import org.eclipse.persistence.jpa.test.mapping.model.BaseEmbeddable;
+import org.eclipse.persistence.jpa.test.mapping.model.BaseParent;
 import org.eclipse.persistence.jpa.test.mapping.model.SimpleMappingEmbeddable;
 import org.eclipse.persistence.jpa.test.mapping.model.SimpleMappingEntity;
 import org.eclipse.persistence.queries.Cursor;
@@ -34,10 +37,14 @@
 
 @RunWith(EmfRunner.class)
 public class TestAggregateObjectMappings {
-    @Emf(createTables = DDLGen.DROP_CREATE,
+    @Emf(name = "cursorEMF" , createTables = DDLGen.DROP_CREATE,
             classes = { SimpleMappingEntity.class, SimpleMappingEmbeddable.class } )
     private EntityManagerFactory emf;
 
+    @Emf(name = "joinEMF" , createTables = DDLGen.DROP_CREATE,
+            classes = { BaseParent.class, BaseChild.class, BaseEmbeddable.class } )
+    private EntityManagerFactory emfTwo;
+
     @Test
     public void testCursorWithAggregateObjectMapping() {
 
@@ -75,4 +82,24 @@
             }
         }
     }
+
+    /**
+     * Test with @JoinColumn that uses a column name that matches the referenced column name
+     */
+    @Test
+    public void testJoinColumnWithSameDuplicateName() {
+
+        EntityManager em = emfTwo.createEntityManager();
+        try {
+            Query query = em.createQuery("SELECT c.parentRef FROM BaseChild c");
+            query.getResultList();
+        } finally {
+            if (em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            if(em.isOpen()) {
+                em.close();
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/model/BaseChild.java b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/model/BaseChild.java
new file mode 100644
index 0000000..e102ed2
--- /dev/null
+++ b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/model/BaseChild.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020 IBM Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+//     04/17/2020 - Will Dazey
+//       - 561664: JoinColumn with same name as referencedColumnName
+package org.eclipse.persistence.jpa.test.mapping.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Embedded;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "BASE_CHILD")
+public class BaseChild {
+
+    @Id
+    @Column(name = "BASE_CHILD_ID")
+    private Long id;
+
+    @Embedded
+    private BaseEmbeddable parentRef;
+}
diff --git a/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/model/BaseEmbeddable.java b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/model/BaseEmbeddable.java
new file mode 100644
index 0000000..bb22b40
--- /dev/null
+++ b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/model/BaseEmbeddable.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020 IBM Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+//     04/17/2020 - Will Dazey
+//       - 561664: JoinColumn with same name as referencedColumnName
+package org.eclipse.persistence.jpa.test.mapping.model;
+
+import jakarta.persistence.Embeddable;
+
+@Embeddable
+public class BaseEmbeddable {
+
+    @jakarta.persistence.ManyToOne
+    @jakarta.persistence.JoinColumn(
+            name = "BASE_PARENT_ID", 
+            referencedColumnName = "BASE_PARENT_ID")
+    private BaseParent parent;
+}
diff --git a/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/model/BaseParent.java b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/model/BaseParent.java
new file mode 100644
index 0000000..dce7223
--- /dev/null
+++ b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/mapping/model/BaseParent.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020 IBM Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+//     04/17/2020 - Will Dazey
+//       - 561664: JoinColumn with same name as referencedColumnName
+package org.eclipse.persistence.jpa.test.mapping.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "BASE_PARENT")
+public class BaseParent {
+
+    @Id
+    @Column(name = "BASE_PARENT_ID")
+    private Long id;
+}