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;
+}