mirror of https://github.com/apache/openjpa.git
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:
parent
da17643624
commit
3182ed978e
|
@ -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;
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue