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);
|
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;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue