问题描述
今天在使用guava cache的时候,报了如下错误:
com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key 50816009. at com.google.common.cache.LocalCache$Segment.getAndRecordStats(LocalCache.java:2346) at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2316) at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2278) at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2193) at com.google.common.cache.LocalCache.get(LocalCache.java:3932) at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3936) at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4806)
之前使用的时候一直都挺正常的,没有出现过此类异常,调用代码如下:
/** 本地缓存 */ private LoadingCache<Long, ServiceInfo> queryByCategoryIdCache = CacheBuilder.newBuilder().refreshAfterWrite(CacheConstants.SERVICE_INFO_CACHE_REFRESH_TIME, TimeUnit.SECONDS) .maximumSize(CacheConstants.MAX_SIZE_PER_CACHE).build(new CacheLoader<Long, ServiceInfo>() { public ServiceInfo load(Long categoryId) { return getServiceInfoByCategoryId(categoryId); } });
@Override public ServiceInfo getServiceInfoByCategoryIdWithCache(long categoryId, boolean withCache) { if (withCache) { try { return queryByCategoryIdCache.get(categoryId); } catch (Throwable t) { logger.error("query serviceInfo exception", t); return null; } } else { return getServiceInfoByCategoryId(categoryId); } }
原因分析
后来又仔细看了下报错信息,大概意思是结果的返回值为null,而guava缓存中又不会存放value为null的数据,导致抛出异常。如果业务流程中,允许存在结果为null的话,只需要捕获到该异常后,返回null就行,可以忽略产生的一次信息。示意代码如下:
@Override public ServiceInfo getServiceInfoByCategoryIdWithCache(long categoryId, boolean withCache) { if (withCache) { try { return queryByCategoryIdCache.get(categoryId); } catch (Throwable t) { return null; } } else { return getServiceInfoByCategoryId(categoryId); } }