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);
if (target == null)
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)
return null;

View File

@ -146,19 +146,47 @@ public class HandlerCollectionTableFieldStrategy
row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
sm);
StoreContext ctx = sm.getContext();
ValueMapping elem = field.getElementMapping();
Column order = field.getOrderColumn();
boolean setOrder = field.getOrderColumnIO().isInsertable(order, false);
int idx = 0;
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);
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)
row.setInt(order, idx);
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)
throws SQLException {
Object obj = sm.fetchObject(field.getIndex());

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.Query;
import junit.framework.Assert;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
public class TestEmbeddable extends SingleEMFTestCase {
@ -83,7 +83,7 @@ public class TestEmbeddable extends SingleEMFTestCase {
VicePresident.class, EntityA_Embed_MappedToOne.class,
Embed_MappedToOne.class, Embed_MappedToOneCascadeDelete.class,
EntityA_Embed_MappedToOneCascadeDelete.class, EntityB2.class,
DROP_TABLES);
Book.class, Listing.class, Seller.class, DROP_TABLES);
}
public void testEntityA_Coll_String() {
@ -179,6 +179,9 @@ public class TestEmbeddable extends SingleEMFTestCase {
updateEntityA_Embed_MappedToOneCascadeDelete();
}
public void testEmbeddableContainingRelationWithGeneratedKey() {
createEmbeddableContainingRelationWithGeneratedKey();
}
/*
* Create EntityA_Coll_String
*/
@ -1877,34 +1880,34 @@ public class TestEmbeddable extends SingleEMFTestCase {
public void assertDepartment1(Department1 d) {
int id = d.getDeptId();
Map<Integer, Employee1> es = d.getEmpMap();
Assert.assertEquals(2,es.size());
assertEquals(2,es.size());
Set keys = es.keySet();
for (Object obj : keys) {
Integer empId = (Integer) obj;
Employee1 e = es.get(empId);
Assert.assertEquals(empId.intValue(), e.getEmpId());
assertEquals(empId.intValue(), e.getEmpId());
}
}
public void assertDepartment2(Department2 d) {
int id = d.getDeptId();
Map<EmployeePK2, Employee2> es = d.getEmpMap();
Assert.assertEquals(2,es.size());
assertEquals(2,es.size());
Set<EmployeePK2> keys = es.keySet();
for (EmployeePK2 pk : keys) {
Employee2 e = es.get(pk);
Assert.assertEquals(pk, e.getEmpPK());
assertEquals(pk, e.getEmpPK());
}
}
public void assertDepartment3(Department3 d) {
int id = d.getDeptId();
Map<EmployeeName3, Employee3> es = d.getEmployees();
Assert.assertEquals(2,es.size());
assertEquals(2,es.size());
Set<EmployeeName3> keys = es.keySet();
for (EmployeeName3 key : keys) {
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) {
int id = item.getId();
Map images = item.getImages();
Assert.assertEquals(numImagesPerItem, images.size());
assertEquals(numImagesPerItem, images.size());
}
public void assertItem2(Item2 item) {
int id = item.getId();
Map images = item.getImages();
Assert.assertEquals(numImagesPerItem, images.size());
assertEquals(numImagesPerItem, images.size());
}
public void assertItem3(Item3 item) {
int id = item.getId();
Map images = item.getImages();
Assert.assertEquals(numImagesPerItem, images.size());
assertEquals(numImagesPerItem, images.size());
}
public void assertCompany1(Company1 c) {
int id = c.getId();
Map organization = c.getOrganization();
Assert.assertEquals(2,organization.size());
assertEquals(2,organization.size());
}
public void assertCompany2(Company2 c) {
int id = c.getId();
Map organization = c.getOrganization();
Assert.assertEquals(2,organization.size());
assertEquals(2,organization.size());
}
public void assertDivision(Division d) {
@ -2145,4 +2148,29 @@ public class TestEmbeddable extends SingleEMFTestCase {
tran.commit();
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);
}
}
}