handle update without recursion correctly in CacheLoader
authorAndreas Müller <a.mueller@bgbm.org>
Mon, 29 Jun 2020 15:04:02 +0000 (17:04 +0200)
committerAndreas Müller <a.mueller@bgbm.org>
Mon, 29 Jun 2020 15:07:48 +0000 (17:07 +0200)
cdmlib-cache/src/main/java/eu/etaxonomy/cdm/cache/CacheLoader.java
cdmlib-cache/src/main/java/eu/etaxonomy/cdm/cache/ProxyUtils.java

index 58161d6578a78bdbc556622bd4c9db4948d9c7e2..ec79628ea81208ab305f9dfd18b38ef67acb541c 100644 (file)
@@ -261,10 +261,13 @@ public class CacheLoader {
         if(isRecursiveEnabled && recursive) {
             if (logger.isDebugEnabled()){logger.debug("---- starting recursive load for cdm entity " + cdmEntity.getClass().getSimpleName() + " with id " + cdmEntity.getId());}
             List<Object> alreadyVisitedEntities = new ArrayList<>();
-            T cb = loadRecursive(cdmEntity, alreadyVisitedEntities, update);
+            loadedCdmBase = loadRecursive(cdmEntity, alreadyVisitedEntities, update);
             alreadyVisitedEntities.clear();
             if (logger.isDebugEnabled()){logger.debug("---- ending recursive load for cdm entity " + cdmEntity.getClass().getSimpleName() + " with id " + cdmEntity.getId() + "\n");}
-            loadedCdmBase =  cb;
+        } else if (update){
+            if (logger.isDebugEnabled()){logger.debug("---- update cdm entity " + cdmEntity.getClass().getSimpleName() + " with id " + cdmEntity.getId());}
+            loadedCdmBase = loadRecursive(cdmEntity, null, update);
+            if (logger.isDebugEnabled()){logger.debug("---- ending update for cdm entity " + cdmEntity.getClass().getSimpleName() + " with id " + cdmEntity.getId() + "\n");}
         } else {
             loadedCdmBase = putToCache(cdmEntity);
         }
@@ -317,7 +320,9 @@ public class CacheLoader {
             String className = deproxiedEntity.getClass().getName();
             CdmModelFieldPropertyFromClass classFields = getFromCdmlibModelCache(className);
             if(classFields != null) {
-                alreadyVisitedEntities.add(cdmEntity);
+                if (alreadyVisitedEntities != null){
+                    alreadyVisitedEntities.add(cdmEntity);
+                }
                 List<String> fields = classFields.getFields();
                 for(String field : fields) {
                     loadField(alreadyVisitedEntities, update, cachedCdmEntity, deproxiedEntity, field);
@@ -340,9 +345,13 @@ public class CacheLoader {
         // retrieve the actual object corresponding to the field.
         // this object will be either a CdmBase or a Collection / Map
         // with CdmBase as the generic type
-        CdmBase cdmEntityInSubGraph = getCdmBaseTypeFieldValue(deproxiedEntity, cachedCdmEntity, field, alreadyVisitedEntities, update);
-        if(cdmEntityInSubGraph != null) {
-            //checkForIdenticalCdmEntity(alreadyVisitedEntities, cdmEntityInSubGraph);
+        Object fieldValue = getAndUpdateFieldVale(deproxiedEntity, cachedCdmEntity, field, alreadyVisitedEntities, update);
+        if (fieldValue instanceof Map && !entityAlreadyVisisted(alreadyVisitedEntities, fieldValue)) {
+            loadRecursiveMap((Map<Object,Object>)fieldValue, alreadyVisitedEntities, update);
+        } else if(fieldValue instanceof Collection && !entityAlreadyVisisted(alreadyVisitedEntities, fieldValue)) {
+            loadRecursiveCollection((Collection<?>)fieldValue, alreadyVisitedEntities, update);
+        } else if (fieldValue instanceof CdmBase) {
+            CdmBase cdmEntityInSubGraph = (CdmBase)fieldValue;
             if(!entityAlreadyVisisted(alreadyVisitedEntities, cdmEntityInSubGraph) ) {
                 if(cdmCacher.ignoreRecursiveLoad(cdmEntityInSubGraph)){
                     if (logger.isDebugEnabled()){logger.debug("recursive load of type " + cdmEntityInSubGraph.getClass().getSimpleName() + " with id " + cdmEntityInSubGraph.getId() + " ignored");}
@@ -353,6 +362,8 @@ public class CacheLoader {
             } else {
                 if (logger.isDebugEnabled()){logger.debug("object of type " + cdmEntityInSubGraph.getClass().getSimpleName() + " with id " + cdmEntityInSubGraph.getId() + " already visited");}
             }
+        } else if (fieldValue != null){
+            throw new IllegalArgumentException("Unhandled field value of type " + fieldValue.getClass().getName() + " for field " + field);
         }
     }
 
@@ -462,7 +473,7 @@ public class CacheLoader {
     }
 
     private boolean entityAlreadyVisisted(List<Object> objList, Object objToCompare) {
-        if(objToCompare != null) {
+        if(objList != null && objToCompare != null) {
             for(Object obj : objList) {
                 if(obj == objToCompare) {
                     return true;
index 2398de74327c9f34501af46c96085765f13bfad3..040e1ead31e4d4ce8f92286321785d20b3f02f9a 100644 (file)
@@ -29,6 +29,7 @@ import org.hibernate.proxy.HibernateProxy;
 import org.hibernate.proxy.LazyInitializer;
 import org.springframework.util.ReflectionUtils;
 
+import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText;
 
 /**
@@ -160,20 +161,11 @@ public class ProxyUtils {
      * De-proxies the passed object <code>o</code> if it is an initialized proxy object,
      * otherwise <code>null</code> is returned.
      */
-    public static Object deproxyOrNull(Object o) {
+    public static <T extends CdmBase> T deproxyOrNull(T o) {
         if(o != null && o instanceof HibernateProxy) {
             LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
             if(!hli.isUninitialized()) {
-                return hli.getImplementation();
-            } else {
-                return null;
-            }
-        }
-
-        if(o != null && o instanceof PersistentCollection) {
-            PersistentCollection pc = ((PersistentCollection)o);
-            if(pc.wasInitialized()) {
-                return  ProxyUtils.getObject(pc);
+                return (T)hli.getImplementation();
             } else {
                 return null;
             }
@@ -181,6 +173,23 @@ public class ProxyUtils {
         return o;
     }
 
+//    /**
+//     * Currently not yet used.
+//     * de-proxies the passed object <code>o</code> if it is an initialized proxy object,
+//     * otherwise <code>null</code> is returned.
+//     */
+//    public static Object deproxyOrNull(Object o) {
+//        if(o != null && o instanceof PersistentCollection) {
+//            PersistentCollection pc = ((PersistentCollection)o);
+//            if(pc.wasInitialized()) {
+//                return ProxyUtils.getObject(pc);
+//            } else {
+//                return null;
+//            }
+//        }
+//        return o;
+//    }
+
     public static boolean isUninitializedProxy(Object o) {
         if(o != null && o instanceof HibernateProxy) {
             LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();