You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2013/05/25 12:30:12 UTC

svn commit: r1486310 - in /ofbiz/branches/release12.04: ./ framework/entity/entitydef/ framework/entity/src/org/ofbiz/entity/ framework/entity/src/org/ofbiz/entity/cache/ framework/entity/src/org/ofbiz/entity/eca/ framework/entity/src/org/ofbiz/entity/...

Author: adrianc
Date: Sat May 25 10:30:12 2013
New Revision: 1486310

URL: http://svn.apache.org/r1486310
Log:
Backported entity cache fixes from the trunk. This commit breaks the rule of no API changes in a release, but I am making an exception here because the methods that were removed should NEVER be used because they GUARANTEE data corruption.


Modified:
    ofbiz/branches/release12.04/   (props changed)
    ofbiz/branches/release12.04/framework/entity/entitydef/entitymodel_test.xml
    ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/Delegator.java
    ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
    ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericValue.java
    ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/AbstractEntityConditionCache.java
    ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/Cache.java
    ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityCache.java
    ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityListCache.java
    ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/eca/EntityEcaHandler.java
    ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java

Propchange: ofbiz/branches/release12.04/
------------------------------------------------------------------------------
  Merged /ofbiz/trunk:r1471284,1471739,1476296,1484279

Modified: ofbiz/branches/release12.04/framework/entity/entitydef/entitymodel_test.xml
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/entitydef/entitymodel_test.xml?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/entitydef/entitymodel_test.xml (original)
+++ ofbiz/branches/release12.04/framework/entity/entitydef/entitymodel_test.xml Sat May 25 10:30:12 2013
@@ -71,6 +71,27 @@ under the License.
         <prim-key field="testingTypeId"/>
     </entity>
   <!-- =========================================================
+    Used for testing views with pks.
+    This simulates the Party->PartyGroup and Party->Person entity relationships.
+  ========================================================= -->
+    <entity entity-name="TestingSubtype" package-name="org.ofbiz.entity.test" title="Testing Subtype Entity">
+        <field name="testingTypeId" type="id-ne" />
+        <field name="subtypeDescription" type="description" />
+        <prim-key field="testingTypeId" />
+    </entity>
+  <!-- =========================================================
+    Used for testing views with pks
+  ========================================================= -->
+    <view-entity entity-name="TestingViewPks" package-name="org.ofbiz.entity.test" title="Testing And TestingSubtype View">
+        <member-entity entity-alias="TST" entity-name="TestingType" />
+        <member-entity entity-alias="TSTSUB" entity-name="TestingSubtype" />
+        <alias-all entity-alias="TST" />
+        <alias-all entity-alias="TSTSUB" />
+        <view-link entity-alias="TST" rel-entity-alias="TSTSUB">
+            <key-map field-name="testingTypeId" />
+        </view-link>
+    </view-entity>
+  <!-- =========================================================
      An entity for testing the BLOB data type
    ========================================================== -->
     <entity entity-name="TestBlob"

Modified: ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/Delegator.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/Delegator.java?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/Delegator.java (original)
+++ ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/Delegator.java Sat May 25 10:30:12 2013
@@ -157,8 +157,9 @@ public interface Delegator {
      * @param primaryKey
      *            The GenericPK to create a value in the datasource from
      * @param doCacheClear
-     *            boolean that specifies whether to clear related cache entries
-     *            for this primaryKey to be created
+     *            boolean that specifies whether or not to automatically clear
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return GenericValue instance containing the new instance
      */
     public GenericValue create(GenericPK primaryKey, boolean doCacheClear) throws GenericEntityException;
@@ -181,7 +182,8 @@ public interface Delegator {
      *            The GenericValue to create a value in the datasource from
      * @param doCacheClear
      *            boolean that specifies whether or not to automatically clear
-     *            cache entries related to this operation
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return GenericValue instance containing the new instance
      */
     public GenericValue create(GenericValue value, boolean doCacheClear) throws GenericEntityException;
@@ -220,7 +222,8 @@ public interface Delegator {
      *            instance
      * @param doCacheClear
      *            boolean that specifies whether or not to automatically clear
-     *            cache entries related to this operation
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return GenericValue instance containing the new or updated instance
      */
     public GenericValue createOrStore(GenericValue value, boolean doCacheClear) throws GenericEntityException;
@@ -864,7 +867,8 @@ public interface Delegator {
      *            GenericValue instance containing the entity to refresh
      * @param doCacheClear
      *            boolean that specifies whether or not to automatically clear
-     *            cache entries related to this operation
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      */
     public void refresh(GenericValue value, boolean doCacheClear) throws GenericEntityException;
 
@@ -913,7 +917,8 @@ public interface Delegator {
      *            or by and fields to remove
      * @param doCacheClear
      *            boolean that specifies whether or not to automatically clear
-     *            cache entries related to this operation
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return int representing number of rows effected by this operation
      */
     public int removeAll(List<? extends GenericEntity> dummyPKs, boolean doCacheClear) throws GenericEntityException;
@@ -927,8 +932,9 @@ public interface Delegator {
      * @param entityName
      *            The Name of the Entity as defined in the entity XML file
      * @param doCacheClear
-     *            boolean that specifies whether to clear cache entries for this
-     *            value to be removed
+     *            boolean that specifies whether or not to automatically clear
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @param fields
      *            The fields of the named entity to query by with their
      *            corresponding values
@@ -959,8 +965,9 @@ public interface Delegator {
      *            The fields of the named entity to query by with their
      *            corresponding values
      * @param doCacheClear
-     *            boolean that specifies whether to clear cache entries for this
-     *            value to be removed
+     *            boolean that specifies whether or not to automatically clear
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return int representing number of rows effected by this operation
      */
     public int removeByAnd(String entityName, Map<String, ? extends Object> fields, boolean doCacheClear) throws GenericEntityException;
@@ -997,8 +1004,9 @@ public interface Delegator {
      * @param condition
      *            The condition used to restrict the removing
      * @param doCacheClear
-     *            boolean that specifies whether to clear cache entries for this
-     *            value to be removed
+     *            boolean that specifies whether or not to automatically clear
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return int representing number of rows effected by this operation
      */
     public int removeByCondition(String entityName, EntityCondition condition, boolean doCacheClear) throws GenericEntityException;
@@ -1018,8 +1026,9 @@ public interface Delegator {
      * @param primaryKey
      *            The primary key of the entity to remove.
      * @param doCacheClear
-     *            boolean that specifies whether to clear cache entries for this
-     *            primaryKey to be removed
+     *            boolean that specifies whether or not to automatically clear
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return int representing number of rows effected by this operation
      */
     public int removeByPrimaryKey(GenericPK primaryKey, boolean doCacheClear) throws GenericEntityException;
@@ -1049,8 +1058,9 @@ public interface Delegator {
      * @param value
      *            GenericValue instance containing the entity
      * @param doCacheClear
-     *            boolean that specifies whether to clear cache entries for this
-     *            value to be removed
+     *            boolean that specifies whether or not to automatically clear
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return int representing number of rows effected by this operation
      */
     public int removeRelated(String relationName, GenericValue value, boolean doCacheClear) throws GenericEntityException;
@@ -1070,8 +1080,9 @@ public interface Delegator {
      * @param value
      *            The GenericValue object of the entity to remove.
      * @param doCacheClear
-     *            boolean that specifies whether to clear cache entries for this
-     *            value to be removed
+     *            boolean that specifies whether or not to automatically clear
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return int representing number of rows effected by this operation
      */
     public int removeValue(GenericValue value, boolean doCacheClear) throws GenericEntityException;
@@ -1113,7 +1124,8 @@ public interface Delegator {
      *            GenericValue instance containing the entity
      * @param doCacheClear
      *            boolean that specifies whether or not to automatically clear
-     *            cache entries related to this operation
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return int representing number of rows effected by this operation
      */
     public int store(GenericValue value, boolean doCacheClear) throws GenericEntityException;
@@ -1150,7 +1162,8 @@ public interface Delegator {
      *            store
      * @param doCacheClear
      *            boolean that specifies whether or not to automatically clear
-     *            cache entries related to this operation
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return int representing number of rows effected by this operation
      */
     public int storeAll(List<GenericValue> values, boolean doCacheClear) throws GenericEntityException;
@@ -1170,7 +1183,8 @@ public interface Delegator {
      *            store
      * @param doCacheClear
      *            boolean that specifies whether or not to automatically clear
-     *            cache entries related to this operation
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @param createDummyFks
      *            boolean that specifies whether or not to automatically create
      *            "dummy" place holder FKs
@@ -1202,8 +1216,9 @@ public interface Delegator {
      * @param condition
      *            The condition that restricts the list of stored values
      * @param doCacheClear
-     *            boolean that specifies whether to clear cache entries for
-     *            these values
+     *            boolean that specifies whether or not to automatically clear
+     *            cache entries related to this operation. This should always be
+     *            <code>true</code> - otherwise you will lose data integrity.
      * @return int representing number of rows effected by this operation
      * @throws GenericEntityException
      */

Modified: ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericDelegator.java?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericDelegator.java (original)
+++ ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericDelegator.java Sat May 25 10:30:12 2013
@@ -996,12 +996,6 @@ public class GenericDelegator implements
 
             GenericHelper helper = getEntityHelper(primaryKey.getEntityName());
 
-            if (doCacheClear) {
-                // always clear cache before the operation
-                ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_REMOVE, primaryKey, false);
-                this.clearCacheLine(primaryKey);
-            }
-
             ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_REMOVE, primaryKey, false);
 
             // if audit log on for any fields, save old value before removing so it's still there
@@ -1014,6 +1008,11 @@ public class GenericDelegator implements
                 removedEntity = this.findOne(primaryKey.getEntityName(), primaryKey, false);
             }
             int num = helper.removeByPrimaryKey(primaryKey);
+            if (doCacheClear) {
+                ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_REMOVE, primaryKey, false);
+                this.clearCacheLine(primaryKey);
+            }
+
             this.saveEntitySyncRemoveInfo(primaryKey);
 
             if (testMode) {
@@ -1065,11 +1064,6 @@ public class GenericDelegator implements
 
             GenericHelper helper = getEntityHelper(value.getEntityName());
 
-            if (doCacheClear) {
-                ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_REMOVE, value, false);
-                this.clearCacheLine(value);
-            }
-
             ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_REMOVE, value, false);
 
             // if audit log on for any fields, save old value before actual remove
@@ -1085,6 +1079,11 @@ public class GenericDelegator implements
             int num = helper.removeByPrimaryKey(value.getPrimaryKey());
             // Need to call removedFromDatasource() here because the helper calls removedFromDatasource() on the PK instead of the GenericEntity.
             value.removedFromDatasource();
+            if (doCacheClear) {
+                ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_REMOVE, value, false);
+                this.clearCacheLine(value);
+            }
+
 
             if (testMode) {
                 if (removedValue != null) {
@@ -1330,12 +1329,6 @@ public class GenericDelegator implements
             ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_STORE, value, false);
             GenericHelper helper = getEntityHelper(value.getEntityName());
 
-            if (doCacheClear) {
-                // always clear cache before the operation
-                ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_STORE, value, false);
-                this.clearCacheLine(value);
-            }
-
             ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_STORE, value, false);
             this.encryptFields(value);
 
@@ -1351,6 +1344,10 @@ public class GenericDelegator implements
             }
 
             int retVal = helper.store(value);
+            if (doCacheClear) {
+                ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_STORE, value, false);
+                this.clearCacheLine(value);
+            }
 
             if (testMode) {
                 storeForTestRollback(new TestOperation(OperationType.UPDATE, updatedEntity));
@@ -2176,11 +2173,6 @@ public class GenericDelegator implements
      * @see org.ofbiz.entity.Delegator#clearCacheLine(org.ofbiz.entity.GenericValue, boolean)
      */
     public void clearCacheLine(GenericValue value, boolean distribute) {
-        // TODO: make this a bit more intelligent by passing in the operation being done (create, update, remove) so we can not do unnecessary cache clears...
-        // for instance:
-        // on create don't clear by primary cache (and won't clear original values because there won't be any)
-        // on remove don't clear by and for new values, but do for original values
-
         // Debug.logInfo("running clearCacheLine for value: " + value + ", distribute: " + distribute, module);
         if (value == null) {
             return;

Modified: ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericValue.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericValue.java?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericValue.java (original)
+++ ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/GenericValue.java Sat May 25 10:30:12 2013
@@ -56,12 +56,6 @@ public class GenericValue extends Generi
         }
     };
 
-    /** Map to cache various related entity collections */
-    public transient Map<String, List<GenericValue>> relatedCache = null;
-
-    /** Map to cache various related cardinality one entity collections */
-    public transient Map<String, GenericValue> relatedOneCache = null;
-
     /** A Map containing the original field values from the database.
      */
     private Map<String, Object> originalDbValues = null;
@@ -105,12 +99,7 @@ public class GenericValue extends Generi
 
     @Override
     public void reset() {
-        // from GenericEntity
         super.reset();
-
-        // from GenericValue
-        this.relatedCache = null;
-        this.relatedOneCache = null;
         this.originalDbValues = null;
     }
 
@@ -245,59 +234,6 @@ public class GenericValue extends Generi
         return this.getRelatedCache(relationName, null, orderBy);
     }
 
-    /** Get the named Related Entity for the GenericValue from the persistent
-     *  store, looking first in a cache associated with this entity which is
-     *  destroyed with this ValueObject when no longer used.
-     *@param relationName String containing the relation name which is the combination of relation.title and relation.rel-entity-name as specified in the entity XML definition file
-     *@return List of GenericValue instances as specified in the relation definition
-     */
-    public List<GenericValue> getRelatedEmbeddedCache(String relationName) throws GenericEntityException {
-        if (relatedCache == null) relatedCache = FastMap.newInstance();
-        List<GenericValue> col = relatedCache.get(relationName);
-
-        if (col == null) {
-            col = getRelated(relationName);
-            relatedCache.put(relationName, col);
-        }
-        return col;
-    }
-
-    /** Get the named Related Entity for the GenericValue from the persistent
-     *  store, looking first in a cache associated with this entity which is
-     *  destroyed with this ValueObject when no longer used.
-     *@param relationName String containing the relation name which is the combination of relation.title and relation.rel-entity-name as specified in the entity XML definition file
-     * @param byAndFields the fields that must equal in order to keep; may be null
-     * @param orderBy The fields of the named entity to order the query by; may be null;
-     *      optionally add a " ASC" for ascending or " DESC" for descending
-     *@return List of GenericValue instances as specified in the relation definition
-     */
-    public List<GenericValue> getRelatedEmbeddedCache(String relationName, Map<String, ? extends Object> byAndFields, List<String> orderBy) throws GenericEntityException {
-        List<GenericValue> col = getRelatedEmbeddedCache(relationName);
-
-        if (byAndFields != null) col = EntityUtil.filterByAnd(col, byAndFields);
-        if (UtilValidate.isNotEmpty(orderBy)) col = EntityUtil.orderBy(col, orderBy);
-        return col;
-    }
-
-    public void removeRelatedEmbeddedCache(String relationName) {
-        if (relatedCache == null) return;
-        relatedCache.remove(relationName);
-    }
-
-    public void storeRelatedEmbeddedCache(String relationName, List<GenericValue> col) {
-        if (relatedCache == null) relatedCache = FastMap.newInstance();
-        relatedCache.put(relationName, col);
-    }
-
-    public void storeRelatedEmbeddedCache(String relationName, GenericValue value) {
-        if (relatedCache == null) relatedCache = FastMap.newInstance();
-        relatedCache.put(relationName, UtilMisc.toList(value));
-    }
-
-    public void clearEmbeddedCache() {
-        relatedCache.clear();
-    }
-
     /** Get the named Related Entity for the GenericValue from the persistent store
      *@param relationName String containing the relation name which is the combination of relation.title and relation.rel-entity-name as specified in the entity XML definition file
      *@return List of GenericValue instances as specified in the relation definition
@@ -315,23 +251,6 @@ public class GenericValue extends Generi
         return this.getDelegator().getRelatedOneCache(relationName, this);
     }
 
-    /** Get the named Related Entity for the GenericValue from the persistent
-     *  store, looking first in a cache associated with this entity which is
-     *  destroyed with this ValueObject when no longer used.
-     *@param relationName String containing the relation name which is the combination of relation.title and relation.rel-entity-name as specified in the entity XML definition file
-     *@return List of GenericValue instances as specified in the relation definition
-     */
-    public GenericValue getRelatedOneEmbeddedCache(String relationName) throws GenericEntityException {
-        if (relatedOneCache == null) relatedOneCache = FastMap.newInstance();
-        GenericValue value = relatedOneCache.get(relationName);
-
-        if (value == null) {
-            value = getRelatedOne(relationName);
-            if (value != null) relatedOneCache.put(relationName, value);
-        }
-        return value;
-    }
-
     /** Get the named Related Entity for the GenericValue from the persistent store and filter it
      *@param relationName String containing the relation name which is the combination of relation.title and relation.rel-entity-name as specified in the entity XML definition file
      *@param fields the fields that must equal in order to keep
@@ -351,17 +270,6 @@ public class GenericValue extends Generi
         return EntityUtil.filterByAnd(this.getDelegator().getRelatedCache(relationName, this), fields);
     }
 
-    /** Get the named Related Entity for the GenericValue from the persistent
-     *  store and filter it, looking first in a cache associated with this entity which is
-     *  destroyed with this ValueObject when no longer used.
-     *@param relationName String containing the relation name which is the combination of relation.title and relation.rel-entity-name as specified in the entity XML definition file
-     *@param fields the fields that must equal in order to keep
-     *@return List of GenericValue instances as specified in the relation definition
-     */
-    public List<GenericValue> getRelatedByAndEmbeddedCache(String relationName, Map<String, ? extends Object> fields) throws GenericEntityException {
-        return EntityUtil.filterByAnd(getRelatedEmbeddedCache(relationName), fields);
-    }
-
     /** Get the named Related Entity for the GenericValue from the persistent store and order it
      *@param relationName String containing the relation name which is the combination of relation.title and relation.rel-entity-name as specified in the entity XML definition file
      *@param orderBy the order that they should be returned
@@ -381,17 +289,6 @@ public class GenericValue extends Generi
         return EntityUtil.orderBy(this.getDelegator().getRelatedCache(relationName, this), orderBy);
     }
 
-    /** Get the named Related Entity for the GenericValue from the persistent
-     *  store and order it, looking first in a cache associated with this entity which is
-     *  destroyed with this ValueObject when no longer used.
-     *@param relationName String containing the relation name which is the combination of relation.title and relation.rel-entity-name as specified in the entity XML definition file
-     *@param orderBy the order that they should be returned
-     *@return List of GenericValue instances as specified in the relation definition
-     */
-    public List<GenericValue> getRelatedOrderByEmbeddedCache(String relationName, List<String> orderBy) throws GenericEntityException {
-        return EntityUtil.orderBy(getRelatedEmbeddedCache(relationName), orderBy);
-    }
-
     /** Remove the named Related Entity for the GenericValue from the persistent store
      *@param relationName String containing the relation name which is the combination of relation.title and relation.rel-entity-name as specified in the entity XML definition file
      */

Modified: ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/AbstractEntityConditionCache.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/AbstractEntityConditionCache.java?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/AbstractEntityConditionCache.java (original)
+++ ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/AbstractEntityConditionCache.java Sat May 25 10:30:12 2013
@@ -61,6 +61,21 @@ public abstract class AbstractEntityCond
         return conditionCache.put(key, value);
     }
 
+    /**
+     * Removes all condition caches that include the specified entity.
+     */
+    public void remove(GenericEntity entity) {
+        UtilCache.clearCache(getCacheName(entity.getEntityName()));
+        ModelEntity model = entity.getModelEntity();
+        if (model != null) {
+            Iterator<String> it = model.getViewConvertorsIterator();
+            while (it.hasNext()) {
+                String targetEntityName = it.next();
+                UtilCache.clearCache(getCacheName(targetEntityName));
+            }
+        }
+    }
+
     public void remove(String entityName, EntityCondition condition) {
         UtilCache<EntityCondition, ConcurrentMap<K, V>> cache = getCache(entityName);
         if (cache == null) return;

Modified: ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/Cache.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/Cache.java?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/Cache.java (original)
+++ ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/Cache.java Sat May 25 10:30:12 2013
@@ -112,16 +112,22 @@ public class Cache {
     public GenericValue remove(GenericEntity entity) {
         if (Debug.verboseOn()) Debug.logVerbose("Cache remove GenericEntity: " + entity, module);
         GenericValue oldEntity = entityCache.remove(entity.getPrimaryKey());
-        entityListCache.storeHook(entity, null);
-        entityObjectCache.storeHook(entity, null);
+        // Workaround because AbstractEntityConditionCache.storeHook doesn't work.
+        entityListCache.remove(entity);
+        entityObjectCache.remove(entity);
+        // entityListCache.storeHook(entity, null);
+        // entityObjectCache.storeHook(entity, null);
         return oldEntity;
     }
 
     public GenericValue remove(GenericPK pk) {
         if (Debug.verboseOn()) Debug.logVerbose("Cache remove GenericPK: " + pk, module);
         GenericValue oldEntity = entityCache.remove(pk);
-        entityListCache.storeHook(pk, null);
-        entityObjectCache.storeHook(pk, null);
+        // Workaround because AbstractEntityConditionCache.storeHook doesn't work.
+        entityListCache.remove(pk);
+        entityObjectCache.remove(pk);
+        // entityListCache.storeHook(pk, null);
+        // entityObjectCache.storeHook(pk, null);
         return oldEntity;
     }
 }

Modified: ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityCache.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityCache.java?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityCache.java (original)
+++ ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityCache.java Sat May 25 10:30:12 2013
@@ -18,11 +18,14 @@
  *******************************************************************************/
 package org.ofbiz.entity.cache;
 
+import java.util.Iterator;
+
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.cache.UtilCache;
 import org.ofbiz.entity.GenericPK;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.model.ModelEntity;
 
 public class EntityCache extends AbstractCache<GenericPK, GenericValue> {
     public static final String module = EntityCache.class.getName();
@@ -77,6 +80,14 @@ public class EntityCache extends Abstrac
         if (Debug.verboseOn()) Debug.logVerbose("Removing from EntityCache with PK [" + pk + "], will remove from this cache: " + (entityCache == null ? "[No cache found to remove from]" : entityCache.getName()), module);
         if (entityCache == null) return null;
         GenericValue retVal = entityCache.remove(pk);
+        ModelEntity model = pk.getModelEntity();
+        if (model != null) {
+            Iterator<String> it = model.getViewConvertorsIterator();
+            while (it.hasNext()) {
+                String targetEntityName = it.next();
+                UtilCache.clearCache(getCacheName(targetEntityName));
+            }
+        }
         if (Debug.verboseOn()) Debug.logVerbose("Removing from EntityCache with PK [" + pk + "], found this in the cache: " + retVal, module);
         return retVal;
     }

Modified: ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityListCache.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityListCache.java?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityListCache.java (original)
+++ ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/cache/EntityListCache.java Sat May 25 10:30:12 2013
@@ -23,8 +23,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentMap;
 
+import org.ofbiz.base.util.Debug;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.util.EntityUtil;
 
 public class EntityListCache extends AbstractEntityConditionCache<Object, List<GenericValue>> {
@@ -65,7 +67,16 @@ public class EntityListCache extends Abs
     }
 
     public List<GenericValue> put(String entityName, EntityCondition condition, List<String> orderBy, List<GenericValue> entities) {
-        return super.put(entityName, getFrozenConditionKey(condition), getOrderByKey(orderBy), entities);
+        ModelEntity entity = this.getDelegator().getModelEntity(entityName);
+        if (entity.getNeverCache()) {
+            Debug.logWarning("Tried to put a value of the " + entityName + " entity in the cache but this entity has never-cache set to true, not caching.", module);
+            return null;
+        }
+        for (GenericValue memberValue : entities) {
+            memberValue.setImmutable();
+        }
+        Map<Object, List<GenericValue>> conditionCache = getOrCreateConditionCache(entityName, getFrozenConditionKey(condition));
+        return conditionCache.put(getOrderByKey(orderBy), entities);
     }
 
     public List<GenericValue> remove(String entityName, EntityCondition condition, List<String> orderBy) {

Modified: ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/eca/EntityEcaHandler.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/eca/EntityEcaHandler.java?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/eca/EntityEcaHandler.java (original)
+++ ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/eca/EntityEcaHandler.java Sat May 25 10:30:12 2013
@@ -34,6 +34,9 @@ public interface EntityEcaHandler<T> {
     public static final String EV_VALIDATE = "validate";
     public static final String EV_RUN = "run";
     public static final String EV_RETURN = "return";
+    /**
+     * Invoked after the entity operation, but before the cache is cleared.
+     */
     public static final String EV_CACHE_CLEAR = "cache-clear";
     public static final String EV_CACHE_CHECK = "cache-check";
     public static final String EV_CACHE_PUT = "cache-put";

Modified: ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java?rev=1486310&r1=1486309&r2=1486310&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java (original)
+++ ofbiz/branches/release12.04/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java Sat May 25 10:30:12 2013
@@ -143,7 +143,6 @@ public class EntityTestSuite extends Ent
         } catch (UnsupportedOperationException e) {
         }
         // Test entity value update operation updates the cache
-        /* Requires revision 1471284, 1476296
         testValue = (GenericValue) testValue.clone();
         testValue.put("description", "New Testing Type #3");
         testValue.store();
@@ -188,9 +187,7 @@ public class EntityTestSuite extends Ent
         testValue.remove();
         testList = delegator.findList("TestingType", testCondition, null, null, null, true);
         assertEquals("Delegator findList returned empty list", 0, testList.size());
-        */
         // Test view entities in the pk cache - updating an entity should clear pk caches for all view entities containing that entity.
-        /* Requires revision 1484279
         testValue = delegator.create("TestingSubtype", "testingTypeId", "TEST-9", "subtypeDescription", "Testing Subtype #9");
         assertNotNull("TestingSubtype created", testValue);
         // Confirm member entity appears in the view
@@ -204,7 +201,6 @@ public class EntityTestSuite extends Ent
         // Check if cached view contains the modification
         testValue = delegator.findOne("TestingViewPks", true, "testingTypeId", "TEST-9");
         assertEquals("View retrieved from cache has the correct member description", "New Testing Subtype #9", testValue.getString("subtypeDescription"));
-        */
     }
 
     /*