Skip to content

Commit

Permalink
Bug 561664: JoinColumn with same name and referencedColumnName throws…
Browse files Browse the repository at this point in the history
… exception

Signed-off-by: Will Dazey <[email protected]>
  • Loading branch information
dazey3 authored and rfelcman committed Apr 23, 2020
1 parent d9fb01d commit c7b4d1a
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1998, 2018 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
Expand Down Expand Up @@ -441,56 +442,59 @@ public Object clone() {
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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019 IBM Corporation. All rights reserved.
* Copyright (c) 2019, 2020 Oracle and/or its affiliates. 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
Expand All @@ -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;
Expand All @@ -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() {

Expand Down Expand Up @@ -75,4 +82,24 @@ public void testCursorWithAggregateObjectMapping() {
}
}
}

/**
* 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();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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 javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "BASE_CHILD")
public class BaseChild {

@Id
@Column(name = "BASE_CHILD_ID")
private Long id;

@Embedded
private BaseEmbeddable parentRef;
}
Original file line number Diff line number Diff line change
@@ -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 javax.persistence.Embeddable;

@Embeddable
public class BaseEmbeddable {

@javax.persistence.ManyToOne
@javax.persistence.JoinColumn(
name = "BASE_PARENT_ID",
referencedColumnName = "BASE_PARENT_ID")
private BaseParent parent;
}
Original file line number Diff line number Diff line change
@@ -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 javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "BASE_PARENT")
public class BaseParent {

@Id
@Column(name = "BASE_PARENT_ID")
private Long id;
}

0 comments on commit c7b4d1a

Please sign in to comment.