OPENJPA-1072: set up foreign key relationship for the relation within an embeddable in an element collection.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@772874 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Fay Wang 2009-05-08 07:48:08 +00:00
parent da17643624
commit 3182ed978e
6 changed files with 296 additions and 14 deletions

View File

@ -161,6 +161,15 @@ public class ValueMappingImpl
return getValueMappedByMapping().getForeignKey(target); return getValueMappedByMapping().getForeignKey(target);
if (target == null) if (target == null)
return _fk; return _fk;
ClassMapping embeddedMeta = (ClassMapping)getEmbeddedMetaData();
if (embeddedMeta != null) {
FieldMapping[] fields = embeddedMeta.getFieldMappings();
for (int i = 0; i < fields.length; i++) {
ValueMapping val = fields[i].getValueMapping();
if (val.getDeclaredTypeMapping() == target)
return val.getForeignKey();
}
}
if (_fk == null && _cols.length == 0) if (_fk == null && _cols.length == 0)
return null; return null;

View File

@ -146,18 +146,46 @@ public class HandlerCollectionTableFieldStrategy
row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(), row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
sm); sm);
StoreContext ctx = sm.getContext();
ValueMapping elem = field.getElementMapping(); ValueMapping elem = field.getElementMapping();
Column order = field.getOrderColumn(); Column order = field.getOrderColumn();
boolean setOrder = field.getOrderColumnIO().isInsertable(order, false); boolean setOrder = field.getOrderColumnIO().isInsertable(order, false);
int idx = 0; int idx = 0;
for (Iterator itr = coll.iterator(); itr.hasNext(); idx++) { for (Iterator itr = coll.iterator(); itr.hasNext(); idx++) {
HandlerStrategies.set(elem, itr.next(), store, row, _cols, Object val = itr.next();
HandlerStrategies.set(elem, val, store, row, _cols,
_io, true); _io, true);
StateManagerImpl esm = (StateManagerImpl)ctx.getStateManager(val);
if (esm != null) {
boolean isEmbedded = esm.isEmbedded();
Collection rels = new ArrayList();
if (isEmbedded) {
getRelations(esm, rels, ctx);
for (Object rel : rels) {
elem.setForeignKey(row, (StateManagerImpl)rel);
}
}
}
if (setOrder) if (setOrder)
row.setInt(order, idx); row.setInt(order, idx);
rm.flushSecondaryRow(row); rm.flushSecondaryRow(row);
} }
} }
private void getRelations(StateManagerImpl sm, Collection rels,
StoreContext ctx) {
FieldMetaData[] fields = sm.getMetaData().getFields();
for (int i = 0; i < fields.length; i++) {
Object obj = sm.fetch(i);
StateManagerImpl esm = (StateManagerImpl)ctx.getStateManager(obj);
if (esm != null) {
if (!esm.isEmbedded())
rels.add(esm);
else
getRelations(esm, rels, ctx);
}
}
}
public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm) public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
throws SQLException { throws SQLException {

View File

@ -0,0 +1,82 @@
/*
* 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.embed;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;
@Entity
@Table(name="BK_EMD")
public class Book {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private long isbn;
@ElementCollection
@CollectionTable(name="listing")
protected Set<Listing> listings = new HashSet<Listing>();
public Book(){}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Book(long isbn){
this.isbn=isbn;
}
public long getIsbc() {
return isbn;
}
public void setIsbc(long isbn) {
this.isbn = isbn;
}
public Set<Listing> getListings() {
return listings;
}
public void setListings(Set<Listing> listings) {
this.listings = listings;
}
public void addListing(Listing l){
listings.add(l);
}
public String toString(){
String res ="Book isbn: " + isbn + "\nListings: ";
for(Listing l : listings){
res+="\t"+l.toString() + "\n";
}
return res.substring(0, res.length()-2);
}
}

View File

@ -0,0 +1,66 @@
/*
* 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.embed;
import javax.persistence.CascadeType;
import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;
@Embeddable
public class Listing {
@ManyToOne(cascade=CascadeType.ALL)
Seller seller;
Double price;
String comments;
public Listing(){}
public Listing(Seller seller, Double price){
this.price=price;
this.seller=seller;
}
public Seller getSeller() {
return seller;
}
public void setSeller(Seller seller) {
this.seller = seller;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
}

View File

@ -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.embed;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="SL_EMD")
public class Seller {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
public Seller(){
}
public Seller(String n){
name=n;
}
/*
public Seller(String n, int id){
name=n;
this.id = id;
}
*/
public int getId() {
return id;
}
/*
public void setId(int id) {
this.id = id;
}
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString(){
return "Seller id: " + id + " name: " + name;
}
}

View File

@ -31,7 +31,7 @@ import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction; import javax.persistence.EntityTransaction;
import javax.persistence.Query; import javax.persistence.Query;
import junit.framework.Assert;
import org.apache.openjpa.persistence.test.SingleEMFTestCase; import org.apache.openjpa.persistence.test.SingleEMFTestCase;
public class TestEmbeddable extends SingleEMFTestCase { public class TestEmbeddable extends SingleEMFTestCase {
@ -83,7 +83,7 @@ public class TestEmbeddable extends SingleEMFTestCase {
VicePresident.class, EntityA_Embed_MappedToOne.class, VicePresident.class, EntityA_Embed_MappedToOne.class,
Embed_MappedToOne.class, Embed_MappedToOneCascadeDelete.class, Embed_MappedToOne.class, Embed_MappedToOneCascadeDelete.class,
EntityA_Embed_MappedToOneCascadeDelete.class, EntityB2.class, EntityA_Embed_MappedToOneCascadeDelete.class, EntityB2.class,
DROP_TABLES); Book.class, Listing.class, Seller.class, DROP_TABLES);
} }
public void testEntityA_Coll_String() { public void testEntityA_Coll_String() {
@ -179,6 +179,9 @@ public class TestEmbeddable extends SingleEMFTestCase {
updateEntityA_Embed_MappedToOneCascadeDelete(); updateEntityA_Embed_MappedToOneCascadeDelete();
} }
public void testEmbeddableContainingRelationWithGeneratedKey() {
createEmbeddableContainingRelationWithGeneratedKey();
}
/* /*
* Create EntityA_Coll_String * Create EntityA_Coll_String
*/ */
@ -1877,34 +1880,34 @@ public class TestEmbeddable extends SingleEMFTestCase {
public void assertDepartment1(Department1 d) { public void assertDepartment1(Department1 d) {
int id = d.getDeptId(); int id = d.getDeptId();
Map<Integer, Employee1> es = d.getEmpMap(); Map<Integer, Employee1> es = d.getEmpMap();
Assert.assertEquals(2,es.size()); assertEquals(2,es.size());
Set keys = es.keySet(); Set keys = es.keySet();
for (Object obj : keys) { for (Object obj : keys) {
Integer empId = (Integer) obj; Integer empId = (Integer) obj;
Employee1 e = es.get(empId); Employee1 e = es.get(empId);
Assert.assertEquals(empId.intValue(), e.getEmpId()); assertEquals(empId.intValue(), e.getEmpId());
} }
} }
public void assertDepartment2(Department2 d) { public void assertDepartment2(Department2 d) {
int id = d.getDeptId(); int id = d.getDeptId();
Map<EmployeePK2, Employee2> es = d.getEmpMap(); Map<EmployeePK2, Employee2> es = d.getEmpMap();
Assert.assertEquals(2,es.size()); assertEquals(2,es.size());
Set<EmployeePK2> keys = es.keySet(); Set<EmployeePK2> keys = es.keySet();
for (EmployeePK2 pk : keys) { for (EmployeePK2 pk : keys) {
Employee2 e = es.get(pk); Employee2 e = es.get(pk);
Assert.assertEquals(pk, e.getEmpPK()); assertEquals(pk, e.getEmpPK());
} }
} }
public void assertDepartment3(Department3 d) { public void assertDepartment3(Department3 d) {
int id = d.getDeptId(); int id = d.getDeptId();
Map<EmployeeName3, Employee3> es = d.getEmployees(); Map<EmployeeName3, Employee3> es = d.getEmployees();
Assert.assertEquals(2,es.size()); assertEquals(2,es.size());
Set<EmployeeName3> keys = es.keySet(); Set<EmployeeName3> keys = es.keySet();
for (EmployeeName3 key : keys) { for (EmployeeName3 key : keys) {
Employee3 e = es.get(key); Employee3 e = es.get(key);
Assert.assertEquals(key, e.getName()); assertEquals(key, e.getName());
} }
} }
@ -2010,31 +2013,31 @@ public class TestEmbeddable extends SingleEMFTestCase {
public void assertItem1(Item1 item) { public void assertItem1(Item1 item) {
int id = item.getId(); int id = item.getId();
Map images = item.getImages(); Map images = item.getImages();
Assert.assertEquals(numImagesPerItem, images.size()); assertEquals(numImagesPerItem, images.size());
} }
public void assertItem2(Item2 item) { public void assertItem2(Item2 item) {
int id = item.getId(); int id = item.getId();
Map images = item.getImages(); Map images = item.getImages();
Assert.assertEquals(numImagesPerItem, images.size()); assertEquals(numImagesPerItem, images.size());
} }
public void assertItem3(Item3 item) { public void assertItem3(Item3 item) {
int id = item.getId(); int id = item.getId();
Map images = item.getImages(); Map images = item.getImages();
Assert.assertEquals(numImagesPerItem, images.size()); assertEquals(numImagesPerItem, images.size());
} }
public void assertCompany1(Company1 c) { public void assertCompany1(Company1 c) {
int id = c.getId(); int id = c.getId();
Map organization = c.getOrganization(); Map organization = c.getOrganization();
Assert.assertEquals(2,organization.size()); assertEquals(2,organization.size());
} }
public void assertCompany2(Company2 c) { public void assertCompany2(Company2 c) {
int id = c.getId(); int id = c.getId();
Map organization = c.getOrganization(); Map organization = c.getOrganization();
Assert.assertEquals(2,organization.size()); assertEquals(2,organization.size());
} }
public void assertDivision(Division d) { public void assertDivision(Division d) {
@ -2145,4 +2148,29 @@ public class TestEmbeddable extends SingleEMFTestCase {
tran.commit(); tran.commit();
em.close(); em.close();
} }
public void createEmbeddableContainingRelationWithGeneratedKey() {
EntityManager em = emf.createEntityManager();
EntityTransaction tran = em.getTransaction();
Book b = new Book(1590596455);
Seller bob = new Seller("Bob's books!");
Seller jim = new Seller("Jim's books!");
Seller mike = new Seller("Mikes's books!");
b.addListing(new Listing(bob , 44.15));
b.addListing(new Listing(jim , 34.15));
b.addListing(new Listing(mike , 14.15));
em.getTransaction().begin();
em.persist(b);
em.getTransaction().commit();
int id = b.getId();
em.clear();
Book b2 = em.find(Book.class, id);
Set<Listing> listings = b2.getListings();
for (Listing listing : listings) {
Seller seller = listing.getSeller();
assertNotNull(seller);
assertTrue(seller.getId() != 0);
}
}
} }