Project

General

Profile

« Previous | Next » 

Revision ba0d4c2f

Added by Cherian Mathew about 9 years ago

httpInvokerServiceClients.xml : set 'CdmServiceRequestExecutor' class as default for all services
ICdmEntitySession, CdmEntitySession, MockCdmEntitySession : added method to update session
ICdmEntitySessionManager, CdmEntitySessionManager, MockCdmEntitySessionManager : added methods to set active session, dispose and update sessions
ProxyUtils : added utility method
EntityCacherDebugResult : corrected method to determine cache corresponding to entity
CdmTransientEntityCacher : corrected put method
CacheLoader : optimised recursive call
CdmServiceCacher : corrected methods to get from cache and load
CdmServiceRequestExecutor : added update result return calls to load

View differences:

eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CacheLoader.java
17 17
import java.util.Map;
18 18
import java.util.Set;
19 19

  
20
import javassist.util.proxy.ProxyFactory;
21 20
import net.sf.ehcache.Cache;
22 21
import net.sf.ehcache.Element;
23 22

  
24 23
import org.apache.log4j.Logger;
25
import org.hibernate.collection.spi.PersistentCollection;
26 24
import org.hibernate.proxy.HibernateProxy;
27 25
import org.hibernate.proxy.LazyInitializer;
28 26
import org.springframework.util.ReflectionUtils;
......
40 38

  
41 39
    private static boolean isRecursiveEnabled = true;
42 40

  
43
    private final ICdmCacher cdmCacher;
41
    protected final ICdmCacher cdmCacher;
44 42

  
45 43
    private final Cache cdmlibModelCache;
46 44

  
47
    private final ICdmCacher cdmServiceCacher;
48 45

  
49 46

  
50 47
    public CacheLoader(ICdmCacher cdmCacher) {
51
        this(cdmCacher, null);
52
    }
53

  
54
    public CacheLoader(ICdmCacher cdmCacher, ICdmCacher cdmServiceCacher) {
55 48
        this.cdmCacher = cdmCacher;
56 49
        this.cdmlibModelCache = CdmRemoteCacheManager.getInstance().getCdmModelGetMethodsCache();
57
        this.cdmServiceCacher = cdmServiceCacher;
50

  
58 51
    }
59 52

  
60 53

  
......
218 211
            return null;
219 212
        }
220 213

  
221

  
222 214
        // start by looking up the cdm entity in the cache
223 215
        CdmBase cachedCdmEntity = cdmCacher.getFromCache(cdmEntity);
224 216

  
......
229 221
            if(cachedCdmEntity == cdmEntity) {
230 222
                return cachedCdmEntity;
231 223
            }
232

  
233 224
        }
234 225

  
235 226
        CdmBase loadedCdmBase;
......
248 239
    }
249 240

  
250 241

  
251
    private CdmBase load(CdmBase cdmEntity) {
242
    protected CdmBase load(CdmBase cdmEntity) {
252 243
        logger.info("loading object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId());
253 244

  
254 245
        cdmEntity = (CdmBase)ProxyUtils.deproxy(cdmEntity);
255 246

  
256
        // start by looking up the cdm entity in the cache
257
        CdmBase cachedCdmEntity = cdmCacher.getFromCache(cdmEntity);
247
        cdmCacher.put(cdmEntity);
248

  
249
        return cdmCacher.getFromCache(cdmEntity);
258 250

  
259
        if(cachedCdmEntity != null) {
260
            // if cdm entity was found in cache then return ...
261
            logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " already exists");
262
            return cachedCdmEntity;
263
        } else {
264
            // ... else save the entity in the cache
265
            cdmCacher.put(cdmEntity);
266
            logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " put in cache");
267
            return cdmEntity;
268
        }
269 251
    }
270 252

  
253

  
271 254
    private CdmBase loadRecursive(CdmBase cdmEntity,  Set<Object> alreadyVisitedEntities, boolean update) {
272 255

  
273 256
        CdmBase cachedCdmEntity = load(cdmEntity);
274
        if(cdmServiceCacher != null && cdmServiceCacher.exists(cachedCdmEntity)) {
275
            return cachedCdmEntity;
276
        }
257

  
277 258

  
278 259
        // we want to recursive through the cdmEntity (and not the cachedCdmEntity)
279 260
        // since there could be new or deleted objects in the cdmEntity sub-graph
......
298 279
                    } else {
299 280
                        logger.info("object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId() + " already visited");
300 281
                    }
301

  
302 282
                }
303 283
            }
304 284
        } else {
305 285
            throw new CdmClientCacheException("CdmEntity with class " + cdmEntity.getClass().getName() + " is not found in the cdmlib model cache. " +
306 286
                    "The cache may be corrupted or not in sync with the latest model version" );
307 287
        }
288

  
308 289
        return cachedCdmEntity;
309 290
    }
310 291

  
......
334 315
            }
335 316
            field.setAccessible(true);
336 317
            Object o = field.get(cdmEntity);
337

  
338
            if(o != null && o instanceof HibernateProxy) {
339
                LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
340
                if(!hli.isUninitialized()) {
341
                    o = ((HibernateProxy) o).getHibernateLazyInitializer().getImplementation();
342
                    field.set(cdmEntity, o);
343
                }
344
            }
345

  
346
            if(o != null && o instanceof PersistentCollection) {
347
                PersistentCollection pc = ((PersistentCollection)o);
348
                if(pc.wasInitialized()) {
349
                    o = ProxyUtils.getObject(pc);
350
                    field.set(cdmEntity, o);
351
                }
352
            }
353

  
318
            o = ProxyUtils.deproxy(o);
319
            field.set(cdmEntity, o);
354 320

  
355 321
            CdmBase cdmEntityInSubGraph = null;
356 322
            if(update) {
357
                // making sure that the field in cached cdm entity is always
358
                // up-to-date by setting to the value of the cdm entity being loaded
359
                // the only exception to this is found below
360
                field.set(cachedCdmEntity, o);
361
            }
362
            if(o != null
363
                    && !ProxyFactory.isProxyClass(o.getClass())
364
                    && !(o instanceof PersistentCollection) ) {
365

  
323
                    // if we are in update mode we have to make the field of the cached entity
324
                    // up-to-date by setting it to the value of the cdm entity being loaded
325
                    // NOTE : two exceptions to this are found below
326
                    field.set(cachedCdmEntity, o);
366 327

  
328
            }
329
            if(o != null && !ProxyUtils.isProxy(o)) {
367 330
                if(CdmBase.class.isAssignableFrom(o.getClass())) {
368 331
                    logger.info("found initialised cdm entity '" + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId());
369 332
                    cdmEntityInSubGraph  = (CdmBase)o;
370 333
                    CdmBase cachedCdmEntityInSubGraph = cdmCacher.getFromCache(cdmEntityInSubGraph);
371 334

  
372
                    // the only exception to updating the field to the latest value
373
                    // is the case where the field has been already initialised, cached and
374
                    // is not the same as the one in the cache, in which case we set the value
375
                    // of the field to the one found in the cache
335
                    Object oldCachedCdmEntityInSubGraph = field.get(cachedCdmEntity);
336
                    if(ProxyUtils.isProxy(oldCachedCdmEntityInSubGraph)) {
337
                        LazyInitializer hli =
338
                                ((HibernateProxy)oldCachedCdmEntityInSubGraph).getHibernateLazyInitializer();
339

  
340
                        if(cdmEntityInSubGraph.getId() == ((Integer)hli.getIdentifier()).intValue()) {
341
                            // exception 1 : is the case where
342
                            // the earlier value of the field in the cached entity
343
                            // was a proxy with the same id then we don't need to
344
                            // update it here as it will be updated on demand,
345
                            // so we reset it to the earlier proxy
346
                            field.set(cachedCdmEntity, oldCachedCdmEntityInSubGraph);
347
                            return null;
348
                        }
349
                    }
350

  
376 351
                    if(cachedCdmEntityInSubGraph != null) {
377 352
                        if(cachedCdmEntityInSubGraph != cdmEntityInSubGraph) {
353
                            // exception 2 : is the case where
354
                            // the field has been already initialised, cached and
355
                            // is not the same as the one in the cache, in which case we set the value
356
                            // of the field to the one found in the cache
378 357
                            logger.info("setting cached + real value to '" + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId());
379 358
                            field.set(cachedCdmEntity, cachedCdmEntityInSubGraph);
380 359
                            field.set(cdmEntity, cachedCdmEntityInSubGraph);
381 360
                        } else {
382
                            // hack to stop the recursion, since the field value object in cdmEntity
361
                            // since the field value object in cdmEntity
383 362
                            // is the same as the field value object in cachedCdmEntity
384
                            cdmEntityInSubGraph = null;
363
                            // we are sure that the its subgraph is also correctly loaded,
364
                            // so we can exit the recursion
365
                            return null;
385 366
                        }
386 367
                    }
387

  
388 368
                } else if(o instanceof Map && !alreadyVisitedEntities.contains(o)) {
389 369
                    loadRecursive((Map)o, alreadyVisitedEntities, update);
390 370
                } else if(o instanceof Collection && !alreadyVisitedEntities.contains(o)) {

Also available in: Unified diff