mirror of https://github.com/apache/openjpa.git
OPENJPA-744 Extra SQL on LAZY/EAGER ManyToOne relation
Further improved for performance when OneToMany is fetch EAGER, the inverse ManyToOne relations are set such that relation fields in entities after detach remain valid. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@704585 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
212ddcefc9
commit
5128ee06a4
|
@ -35,6 +35,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.apache.openjpa.enhance.PersistenceCapable;
|
||||||
import org.apache.openjpa.event.OrphanedKeyAction;
|
import org.apache.openjpa.event.OrphanedKeyAction;
|
||||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||||
import org.apache.openjpa.jdbc.conf.QuerySQLCacheValue;
|
import org.apache.openjpa.jdbc.conf.QuerySQLCacheValue;
|
||||||
|
@ -355,6 +356,14 @@ public class JDBCStoreManager
|
||||||
Object mappedByObject = info.result.getMappedByValue();
|
Object mappedByObject = info.result.getMappedByValue();
|
||||||
if (mappedByFieldMapping != null && mappedByObject != null)
|
if (mappedByFieldMapping != null && mappedByObject != null)
|
||||||
if (mappedByObject instanceof OpenJPAId)
|
if (mappedByObject instanceof OpenJPAId)
|
||||||
|
// The inverse relation can not be set since
|
||||||
|
// we are eagerly loading this sm for
|
||||||
|
// a sm owner that is still in the process of
|
||||||
|
// initializing itself.
|
||||||
|
// Remember owner oid by setIntermediate().
|
||||||
|
// The inverse relation is set later by
|
||||||
|
// setInverseRelation() when the sm owner is fully
|
||||||
|
// initialized.
|
||||||
sm.setIntermediate(mappedByFieldMapping.getIndex(),
|
sm.setIntermediate(mappedByFieldMapping.getIndex(),
|
||||||
mappedByObject);
|
mappedByObject);
|
||||||
else
|
else
|
||||||
|
@ -366,6 +375,7 @@ public class JDBCStoreManager
|
||||||
mapping = (ClassMapping) sm.getMetaData();
|
mapping = (ClassMapping) sm.getMetaData();
|
||||||
load(mapping, sm, fetch, res);
|
load(mapping, sm, fetch, res);
|
||||||
getVersion(mapping, sm, res);
|
getVersion(mapping, sm, res);
|
||||||
|
setInverseRelation(sm, mapping, res);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -374,6 +384,47 @@ public class JDBCStoreManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setInverseRelation(OpenJPAStateManager owner,
|
||||||
|
ClassMapping mapping, Result res) {
|
||||||
|
FieldMapping[] fms = mapping.getFieldMappings();
|
||||||
|
|
||||||
|
// At this point, the owner is fully initialized.
|
||||||
|
// Check if the owner has eagerly loaded ToMany relations.
|
||||||
|
for (int i = 0; i < fms.length; i++) {
|
||||||
|
if (res.getEager(fms[i]) != null) {
|
||||||
|
Object coll = owner.fetchObject(fms[i].getIndex());
|
||||||
|
if (coll instanceof Collection &&
|
||||||
|
((Collection) coll).size() > 0) {
|
||||||
|
// Found eagerly loaded collection.
|
||||||
|
// Publisher (1) <==> (M) Magazine
|
||||||
|
// publisher has a EAGER OneToMany relation
|
||||||
|
// magazine has a EAGER or LAZY ManyToOne publisher
|
||||||
|
// For each member (Magazine) in the collection,
|
||||||
|
// set its inverse relation (Publisher).
|
||||||
|
for (Iterator itr = ((Collection) coll).iterator();
|
||||||
|
itr.hasNext();) {
|
||||||
|
PersistenceCapable pc = (PersistenceCapable) itr.next();
|
||||||
|
OpenJPAStateManager sm = (OpenJPAStateManager) pc.
|
||||||
|
pcGetStateManager();
|
||||||
|
FieldMapping[] fmd = ((ClassMapping) sm.getMetaData()).
|
||||||
|
getFieldMappings();
|
||||||
|
for (int j = 0; j < fmd.length; j++) {
|
||||||
|
Object oid = sm.getIntermediate(fmd[j].getIndex());
|
||||||
|
// if oid was setIntermediate() previously
|
||||||
|
// and it is the same as the owner,
|
||||||
|
// then set the inverse relation
|
||||||
|
if (oid != null &&
|
||||||
|
oid.equals(owner.getObjectId())) {
|
||||||
|
sm.storeObject(fmd[j].getIndex(),
|
||||||
|
owner.getPersistenceCapable());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void setMappedBy(OpenJPAStateManager sm,
|
protected void setMappedBy(OpenJPAStateManager sm,
|
||||||
FieldMapping mappedByFieldMapping, Object mappedByObject) {
|
FieldMapping mappedByFieldMapping, Object mappedByObject) {
|
||||||
ClassMapping mapping = (ClassMapping) sm.getMetaData();
|
ClassMapping mapping = (ClassMapping) sm.getMetaData();
|
||||||
|
|
|
@ -235,6 +235,7 @@ public class TestInverseEagerSQL
|
||||||
assertEquals(2, sql.size());
|
assertEquals(2, sql.size());
|
||||||
|
|
||||||
sql.clear();
|
sql.clear();
|
||||||
|
em.clear();
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
Publisher p = (Publisher) list.get(i);
|
Publisher p = (Publisher) list.get(i);
|
||||||
Set<Magazine> magazines = p.getMagazineCollection();
|
Set<Magazine> magazines = p.getMagazineCollection();
|
||||||
|
|
Loading…
Reference in New Issue