You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2008/10/13 06:37:49 UTC
svn commit: r703912 - in /openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/
openjpa-per...
Author: fancy
Date: Sun Oct 12 21:37:48 2008
New Revision: 703912
URL: http://svn.apache.org/viewvc?rev=703912&view=rev
Log:
OPENJPA-744 OneToMany EAGER loading generates extra SQLs on inverse ManyToOne relation
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Publisher.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=703912&r1=703911&r2=703912&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Sun Oct 12 21:37:48 2008
@@ -354,7 +354,11 @@
getMappedByFieldMapping();
Object mappedByObject = info.result.getMappedByValue();
if (mappedByFieldMapping != null && mappedByObject != null)
- setMappedBy(sm, mappedByFieldMapping, mappedByObject);
+ if (mappedByObject instanceof OpenJPAId)
+ sm.setIntermediate(mappedByFieldMapping.getIndex(),
+ mappedByObject);
+ else
+ setMappedBy(sm, mappedByFieldMapping, mappedByObject);
}
// load the selected mappings into the given state manager
if (res != null) {
@@ -914,9 +918,29 @@
ConnectionInfo info = new ConnectionInfo();
info.result = result;
info.mapping = mapping;
+
+ // if inverse relation is known, exclude loading during find
+ exclude = excludeInverseRelation(mapping, info, exclude);
return _ctx.find(oid, fetch, exclude, info, 0);
}
+ private BitSet excludeInverseRelation(ClassMapping mapping,
+ ConnectionInfo info, BitSet exclude) {
+ FieldMapping inverse = info.result.getMappedByFieldMapping();
+ if (inverse != null) {
+ FieldMapping[] fms = mapping.getDefinedFieldMappings();
+ if (exclude == null)
+ exclude = new BitSet(fms.length);
+ for (int i = 0; i < fms.length; i++) {
+ if (fms[i] == inverse) {
+ exclude.set(fms[i].getIndex());
+ break;
+ }
+ }
+ }
+ return exclude;
+ }
+
/**
* Load the given state manager with data from the result set. Only
* mappings originally selected will be loaded.
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java?rev=703912&r1=703911&r2=703912&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java Sun Oct 12 21:37:48 2008
@@ -312,8 +312,8 @@
if (field.getOrderColumn() != null)
seq = res.getInt(field.getOrderColumn(), orderJoins) + 1;
- // for inverseEager field
- setMappedBy(oid, sm, coll, res);
+ // for inverse relation field
+ setMappedBy(oid, res);
Object val = loadElement(null, store, fetch, res, dataJoins);
add(store, coll, val);
}
@@ -322,6 +322,23 @@
return rels;
}
+ private void setMappedBy(Object oid, Result res) {
+ // for inverse toOne relation field
+ FieldMapping mappedByFieldMapping = field.getMappedByMapping();
+
+ if (mappedByFieldMapping != null) {
+ ValueMapping val = mappedByFieldMapping.getValueMapping();
+ ClassMetaData decMeta = val.getTypeMetaData();
+ // this inverse field does not have corresponding classMapping
+ // its value may be a collection/map etc.
+ if (decMeta == null)
+ return;
+
+ res.setMappedByFieldMapping(mappedByFieldMapping);
+ res.setMappedByValue(oid);
+ }
+ }
+
private void setMappedBy(Object oid, OpenJPAStateManager sm, Object coll,
Result res) {
// for inverseEager field
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Publisher.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Publisher.java?rev=703912&r1=703911&r2=703912&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Publisher.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Publisher.java Sun Oct 12 21:37:48 2008
@@ -21,6 +21,7 @@
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
@@ -38,7 +39,7 @@
@Column(name="name")
private String name;
- @OneToMany(mappedBy="idPublisher")
+ @OneToMany(mappedBy="idPublisher", fetch=FetchType.EAGER)
private Set<Magazine> magazineCollection;
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java?rev=703912&r1=703911&r2=703912&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java Sun Oct 12 21:37:48 2008
@@ -21,12 +21,16 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
+
import javax.persistence.EntityManager;
import javax.persistence.Query;
import junit.textui.TestRunner;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.query.Magazine;
+import org.apache.openjpa.persistence.query.Publisher;
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
@@ -36,7 +40,8 @@
public void setUp() {
setUp(Customer.class, Customer.CustomerKey.class, Order.class,
EntityAInverseEager.class, EntityA1InverseEager.class, EntityA2InverseEager.class,
- EntityBInverseEager.class, EntityCInverseEager.class, EntityDInverseEager.class);
+ EntityBInverseEager.class, EntityCInverseEager.class, EntityDInverseEager.class,
+ Publisher.class, Magazine.class);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
@@ -93,7 +98,29 @@
c1.setD(d1);
d1.setC(c1);
}
-
+
+ Publisher p1 = new Publisher();
+ p1.setName("publisher1");
+ em.persist(p1);
+
+ for (int i = 0; i < 4; i++) {
+ Magazine magazine = new Magazine();
+ magazine.setIdPublisher(p1);
+ magazine.setName("magagine"+i+"_"+p1.getName());
+ em.persist(magazine);
+ }
+
+ Publisher p2 = new Publisher();
+ p2.setName("publisher2");
+ em.persist(p2);
+
+ for (int i = 0; i < 4; i++) {
+ Magazine magazine = new Magazine();
+ magazine.setIdPublisher(p2);
+ magazine.setName("magagine"+i+"_"+p2.getName());
+ em.persist(magazine);
+ }
+
em.flush();
em.getTransaction().commit();
em.close();
@@ -197,6 +224,32 @@
em.close();
}
+ public void testOneToManyEagerInverseLazyQuery() {
+ sql.clear();
+
+ OpenJPAEntityManager em = emf.createEntityManager();
+ String query = "select p FROM Publisher p";
+ Query q = em.createQuery(query);
+ List list = q.getResultList();
+ assertEquals(2, list.size());
+ assertEquals(2, sql.size());
+
+ sql.clear();
+ for (int i = 0; i < list.size(); i++) {
+ Publisher p = (Publisher) list.get(i);
+ Set<Magazine> magazines = p.getMagazineCollection();
+ assertEquals(4, magazines.size());
+ for (Iterator iter = magazines.iterator(); iter.hasNext();) {
+ Magazine m = (Magazine) iter.next();
+ Publisher mp = m.getIdPublisher();
+ assertEquals(p, mp);
+ }
+ }
+
+ assertEquals(0, sql.size());
+ em.close();
+ }
+
public static void main(String[] args) {
TestRunner.run(TestInverseEagerSQL.class);
}