mirror of
https://github.com/apache/openjpa.git
synced 2025-03-06 16:39:11 +00:00
OPENJPA-2175 Fix problem with multiple foreign keys of the same type
git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/2.1.x@1339677 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0176a4005c
commit
f80acc3f91
@ -1117,6 +1117,10 @@ public class FieldMapping
|
||||
throws SQLException {
|
||||
_val.setForeignKey(row, sm);
|
||||
}
|
||||
public void setForeignKey(Row row, OpenJPAStateManager sm, int targetNumber)
|
||||
throws SQLException {
|
||||
_val.setForeignKey(row, sm, targetNumber);
|
||||
}
|
||||
|
||||
public void whereForeignKey(Row row, OpenJPAStateManager sm)
|
||||
throws SQLException {
|
||||
|
@ -178,6 +178,13 @@ public interface ValueMapping
|
||||
*/
|
||||
public void setForeignKey(Row row, OpenJPAStateManager rel)
|
||||
throws SQLException;
|
||||
/**
|
||||
* Sets this value's foreign key to the given related object. The object
|
||||
* may be null. If the object is one of2or more foreign keys with the
|
||||
* same target, the targetNumber specifies the one to set.
|
||||
*/
|
||||
public void setForeignKey(Row row, OpenJPAStateManager rel, int targetNumber)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Sets this value's foreign key to the given related object. The object
|
||||
|
@ -159,7 +159,7 @@ public class ValueMappingImpl
|
||||
_join = JOIN_FORWARD;
|
||||
}
|
||||
|
||||
public ForeignKey getForeignKey(ClassMapping target) {
|
||||
public ForeignKey getForeignKey(ClassMapping target, int targetNumber) {
|
||||
if (_fk == null && getValueMappedBy() != null)
|
||||
return getValueMappedByMapping().getForeignKey(target);
|
||||
if (target == null)
|
||||
@ -167,10 +167,15 @@ public class ValueMappingImpl
|
||||
ClassMapping embeddedMeta = (ClassMapping)getEmbeddedMetaData();
|
||||
if (embeddedMeta != null) {
|
||||
FieldMapping[] fields = embeddedMeta.getFieldMappings();
|
||||
int j = 0;
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
ValueMapping val = fields[i].getValueMapping();
|
||||
if (val.getDeclaredTypeMapping() == target)
|
||||
if (val.getDeclaredTypeMapping() == target) {
|
||||
if (targetNumber == j)
|
||||
return val.getForeignKey();
|
||||
else
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_fk == null && _cols.length == 0)
|
||||
@ -198,7 +203,9 @@ public class ValueMappingImpl
|
||||
return newfk;
|
||||
}
|
||||
}
|
||||
|
||||
public ForeignKey getForeignKey(ClassMapping target) {
|
||||
return getForeignKey(target, 0);
|
||||
}
|
||||
/**
|
||||
* Create a forward foreign key to the given target.
|
||||
*/
|
||||
@ -323,11 +330,12 @@ public class ValueMappingImpl
|
||||
_join = direction;
|
||||
}
|
||||
|
||||
public void setForeignKey(Row row, OpenJPAStateManager rel)
|
||||
public void setForeignKey(Row row, OpenJPAStateManager rel, int targetNumber)
|
||||
throws SQLException {
|
||||
if (rel != null)
|
||||
row.setForeignKey(getForeignKey((ClassMapping) rel.getMetaData()),
|
||||
if (rel != null) {
|
||||
row.setForeignKey(getForeignKey((ClassMapping) rel.getMetaData(), targetNumber),
|
||||
_io, rel);
|
||||
}
|
||||
else if (_fk != null)
|
||||
row.setForeignKey(_fk, _io, null);
|
||||
else {
|
||||
@ -340,6 +348,11 @@ public class ValueMappingImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setForeignKey(Row row, OpenJPAStateManager rel)
|
||||
throws SQLException {
|
||||
setForeignKey(row, rel, 0);
|
||||
}
|
||||
|
||||
public void whereForeignKey(Row row, OpenJPAStateManager rel)
|
||||
throws SQLException {
|
||||
|
@ -161,8 +161,17 @@ public class HandlerCollectionTableFieldStrategy
|
||||
Collection rels = new ArrayList();
|
||||
if (isEmbedded) {
|
||||
getRelations(esm, rels, ctx);
|
||||
Map<ClassMapping,Integer> targets = new HashMap<ClassMapping,Integer>();
|
||||
for (Object rel : rels) {
|
||||
elem.setForeignKey(row, (StateManagerImpl)rel);
|
||||
StateManagerImpl relSm = (StateManagerImpl)rel;
|
||||
ClassMapping cm =(ClassMapping) relSm.getMetaData();
|
||||
if(!targets.containsKey(cm)){
|
||||
targets.put(cm, 0);
|
||||
}
|
||||
Integer n = targets.get(cm);
|
||||
elem.setForeignKey(row, (StateManagerImpl)rel, n);
|
||||
n++;
|
||||
targets.put(cm, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.foreign.keys;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Embeddable
|
||||
public class ContainsMultSimpleEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8576236113079133657L;
|
||||
|
||||
@ManyToOne(cascade=CascadeType.ALL)
|
||||
@JoinColumn(nullable=false)
|
||||
private SimpleEntity simpleEntity1;
|
||||
|
||||
@ManyToOne(cascade=CascadeType.ALL)
|
||||
@JoinColumn(nullable=false)
|
||||
private SimpleEntity simpleEntity2;
|
||||
|
||||
@ManyToOne(cascade=CascadeType.ALL)
|
||||
@JoinColumn(nullable=false)
|
||||
private SimpleEntity simpleEntity3;
|
||||
|
||||
public SimpleEntity getSimpleEntity1() {
|
||||
return simpleEntity1;
|
||||
}
|
||||
|
||||
public void setSimpleEntity1(SimpleEntity simpleEntity1) {
|
||||
this.simpleEntity1 = simpleEntity1;
|
||||
}
|
||||
|
||||
public SimpleEntity getSimpleEntity2() {
|
||||
return simpleEntity2;
|
||||
}
|
||||
|
||||
public void setSimpleEntity2(SimpleEntity simpleEntity2) {
|
||||
this.simpleEntity2 = simpleEntity2;
|
||||
}
|
||||
|
||||
public SimpleEntity getSimpleEntity3() {
|
||||
return simpleEntity3;
|
||||
}
|
||||
|
||||
public void setSimpleEntity3(SimpleEntity simpleEntity3) {
|
||||
this.simpleEntity3 = simpleEntity3;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.foreign.keys;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name="FK_SIMPLE")
|
||||
public class SimpleEntity implements Serializable {
|
||||
private static final long serialVersionUID = -7535244143281520213L;
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.foreign.keys;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
|
||||
|
||||
/**
|
||||
* Test multiple keys that have the same Entity as
|
||||
* the type.
|
||||
*/
|
||||
public class TestMultForeignKeys extends SQLListenerTestCase {
|
||||
public void setUp() {
|
||||
setUp(SimpleEntity.class,
|
||||
ContainsMultSimpleEntity.class,
|
||||
TopLevel.class,
|
||||
DROP_TABLES);
|
||||
assertNotNull(emf);
|
||||
|
||||
create();
|
||||
}
|
||||
|
||||
public void testCreated() {
|
||||
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
TopLevel tl = em.find(TopLevel.class, 1);
|
||||
assertNotNull(tl);
|
||||
|
||||
ArrayList<ContainsMultSimpleEntity> contMultSEColl =
|
||||
(ArrayList<ContainsMultSimpleEntity>)tl.getContMultSEColl();
|
||||
assertNotNull(contMultSEColl);
|
||||
assertEquals(contMultSEColl.size(), 1);
|
||||
|
||||
ContainsMultSimpleEntity contMultSE = contMultSEColl.get(0);
|
||||
assertNotNull(contMultSE);
|
||||
|
||||
SimpleEntity se1 = contMultSE.getSimpleEntity1();
|
||||
assertNotNull(se1);
|
||||
assertEquals(se1.getId(), 1);
|
||||
assertEquals(se1.getName(), "name1");
|
||||
|
||||
SimpleEntity se2 = contMultSE.getSimpleEntity2();
|
||||
assertNotNull(se2);
|
||||
assertEquals(se2.getId(), 2);
|
||||
assertEquals(se2.getName(), "name2");
|
||||
|
||||
SimpleEntity se3 = contMultSE.getSimpleEntity3();
|
||||
assertNotNull(se3);
|
||||
assertEquals(se3.getId(), 3);
|
||||
assertEquals(se3.getName(), "name3");
|
||||
|
||||
em.close();
|
||||
}
|
||||
|
||||
private void create() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
assertNotNull(em);
|
||||
em.getTransaction().begin();
|
||||
|
||||
ContainsMultSimpleEntity contMultSE = new ContainsMultSimpleEntity();
|
||||
|
||||
SimpleEntity se3 = new SimpleEntity();
|
||||
se3.setId(3);
|
||||
se3.setName("name3");
|
||||
|
||||
SimpleEntity se1 = new SimpleEntity();
|
||||
se1.setId(1);
|
||||
se1.setName("name1");
|
||||
|
||||
SimpleEntity se2 = new SimpleEntity();
|
||||
se2.setId(2);
|
||||
se2.setName("name2");
|
||||
|
||||
contMultSE.setSimpleEntity3(se3);
|
||||
contMultSE.setSimpleEntity1(se1);
|
||||
contMultSE.setSimpleEntity2(se2);
|
||||
|
||||
Collection<ContainsMultSimpleEntity> contMultSEColl = new ArrayList<ContainsMultSimpleEntity>();
|
||||
contMultSEColl.add(contMultSE);
|
||||
|
||||
TopLevel tl = new TopLevel();
|
||||
tl.setId(1);
|
||||
tl.setContMultSEColl(contMultSEColl);
|
||||
|
||||
em.persist(tl);
|
||||
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.foreign.keys;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class TopLevel implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4677719724853263855L;
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
|
||||
@ElementCollection
|
||||
private Collection<ContainsMultSimpleEntity> contMultSEColl;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Collection<ContainsMultSimpleEntity> getContMultSEColl() {
|
||||
return contMultSEColl;
|
||||
}
|
||||
|
||||
public void setContMultSEColl(Collection<ContainsMultSimpleEntity> contMultSEColl) {
|
||||
this.contMultSEColl = contMultSEColl;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user