mirror of https://github.com/apache/openjpa.git
OPENJPA-521. This is a partial fix; we should be able to avoid the looping in clearInverseRelationCache with a bit of extra data structures in FieldMetaData, probably populated during FieldMetaData.getOrder() or MetaDataRepository.newOrder().
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@630063 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4c70963f1a
commit
c5309299b5
|
@ -20,10 +20,11 @@ package org.apache.openjpa.datacache;
|
||||||
|
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
|
||||||
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
|
||||||
import org.apache.openjpa.kernel.AbstractPCData;
|
import org.apache.openjpa.kernel.AbstractPCData;
|
||||||
|
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||||
import org.apache.openjpa.kernel.PCData;
|
import org.apache.openjpa.kernel.PCData;
|
||||||
import org.apache.openjpa.kernel.PCDataImpl;
|
import org.apache.openjpa.kernel.PCDataImpl;
|
||||||
|
import org.apache.openjpa.kernel.PCState;
|
||||||
import org.apache.openjpa.kernel.StoreContext;
|
import org.apache.openjpa.kernel.StoreContext;
|
||||||
import org.apache.openjpa.meta.ClassMetaData;
|
import org.apache.openjpa.meta.ClassMetaData;
|
||||||
import org.apache.openjpa.meta.FieldMetaData;
|
import org.apache.openjpa.meta.FieldMetaData;
|
||||||
|
@ -119,6 +120,65 @@ public class DataCachePCDataImpl
|
||||||
super.store(sm, fields);
|
super.store(sm, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store field-level information from the given state manager.
|
||||||
|
* Special process of checking if the cached collection data is out of order.
|
||||||
|
*/
|
||||||
|
protected void storeField(OpenJPAStateManager sm, FieldMetaData fmd) {
|
||||||
|
if (fmd.getManagement() != fmd.MANAGE_PERSISTENT)
|
||||||
|
return;
|
||||||
|
int index = fmd.getIndex();
|
||||||
|
|
||||||
|
// if the field is a collection and has "order by" set, don't cache
|
||||||
|
// it if this store is coming from a create or update (i.e., only
|
||||||
|
// enlist in cache if this is coming from a database read).
|
||||||
|
if (fmd.getOrders().length > 0) {
|
||||||
|
if (sm.getPCState() == PCState.PNEW)
|
||||||
|
return;
|
||||||
|
if (sm.getPCState() == PCState.PDIRTY) {
|
||||||
|
clearData(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.storeField(sm, fmd);
|
||||||
|
|
||||||
|
// If this field is used in "order by", we need to invalidate cache
|
||||||
|
// for the collection that refer to this field.
|
||||||
|
if (sm.getPCState() == PCState.PDIRTY) {
|
||||||
|
clearInverseRelationCache(sm, fmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this field is in use of "order by" by other field collections
|
||||||
|
* in inverse relation. If it is, clear the other field cache because it
|
||||||
|
* could be out of order.
|
||||||
|
*/
|
||||||
|
protected void clearInverseRelationCache(OpenJPAStateManager sm,
|
||||||
|
FieldMetaData fmd) {
|
||||||
|
ClassMetaData cmd = sm.getMetaData();
|
||||||
|
FieldMetaData[] fields = cmd.getFields();
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
FieldMetaData[] inverses = fields[i].getInverseMetaDatas();
|
||||||
|
if (inverses.length == 0)
|
||||||
|
continue;
|
||||||
|
for (int j = 0; j < inverses.length; j++) {
|
||||||
|
if (inverses[j].getOrderDeclaration()
|
||||||
|
.indexOf(fmd.getName()) != -1) {
|
||||||
|
DataCache cache = sm.getMetaData().getDataCache();
|
||||||
|
Object oid = sm.getContext().getObjectId(sm.fetch(i));
|
||||||
|
DataCachePCData data = cache.get(oid);
|
||||||
|
if ((data != null) &&
|
||||||
|
(data instanceof DataCachePCDataImpl)) {
|
||||||
|
((DataCachePCDataImpl) data)
|
||||||
|
.clearData(inverses[j].getIndex());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected Object toData(FieldMetaData fmd, Object val, StoreContext ctx) {
|
protected Object toData(FieldMetaData fmd, Object val, StoreContext ctx) {
|
||||||
// avoid caching large result set fields
|
// avoid caching large result set fields
|
||||||
if (fmd.isLRS() || fmd.isStream())
|
if (fmd.isLRS() || fmd.isStream())
|
||||||
|
|
Loading…
Reference in New Issue