#1876 - findMap() does not use/hit natural key cache

This commit is contained in:
rob bygrave
2019-12-02 18:37:42 +13:00
parent e093675444
commit 5f8690fb87
4 changed files with 160 additions and 19 deletions
@@ -1245,16 +1245,13 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
public <T> Set<T> findSet(Query<T> query, Transaction t) {
SpiOrmQueryRequest request = createQueryRequest(Type.SET, query, t);
Object result = request.getFromQueryCache();
if (result != null) {
return (Set<T>) result;
}
try {
request.initTransIfRequired();
return request.findSet();
} finally {
request.endTransIfRequired();
}
@@ -1265,16 +1262,18 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
public <K, T> Map<K, T> findMap(Query<T> query, Transaction t) {
SpiOrmQueryRequest request = createQueryRequest(Type.MAP, query, t);
request.resetBeanCacheAutoMode(false);
if ((t == null || !t.isSkipCache()) && request.getFromBeanCache()) {
// hit bean cache and got all results from cache
return request.getBeanCacheHitsAsMap();
}
Object result = request.getFromQueryCache();
if (result != null) {
return (Map<K, T>) result;
}
try {
request.initTransIfRequired();
return request.findMap();
} finally {
request.endTransIfRequired();
}
@@ -10,6 +10,7 @@ import io.ebean.bean.EntityBean;
import io.ebean.bean.PersistenceContext;
import io.ebean.cache.QueryCacheEntry;
import io.ebean.common.BeanList;
import io.ebean.common.BeanMap;
import io.ebean.common.CopyOnFirstWriteList;
import io.ebean.event.BeanFindController;
import io.ebean.event.BeanQueryAdapter;
@@ -31,6 +32,7 @@ import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import io.ebeaninternal.server.deploy.DeployParser;
import io.ebeaninternal.server.deploy.DeployPropertyParserMap;
import io.ebeaninternal.server.el.ElPropertyValue;
import io.ebeaninternal.server.loadcontext.DLoadContext;
import io.ebeaninternal.server.query.CQueryPlan;
import io.ebeaninternal.server.query.CancelableQuery;
@@ -586,19 +588,36 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
public void mergeCacheHits(BeanCollection<T> result) {
if (cacheBeans != null && !cacheBeans.isEmpty()) {
for (T hit : cacheBeans) {
result.internalAdd(hit);
if (query.getType() == Type.MAP) {
mergeCacheHitsToMap(result);
} else {
mergeCacheHitsToList(result);
}
// resort in memory here after merging the cache hits with the DB hits
if (result instanceof BeanList) {
OrderBy<T> orderBy = query.getOrderBy();
if (orderBy != null) {
beanDescriptor.sort(((BeanList<T>)result).getActualList(), orderBy.toStringFormat());
}
}
}
private void mergeCacheHitsToList(BeanCollection<T> result) {
for (T hit : cacheBeans) {
result.internalAdd(hit);
}
if (result instanceof BeanList) {
OrderBy<T> orderBy = query.getOrderBy();
if (orderBy != null) {
// in memory sort after merging the cache hits with the DB hits
beanDescriptor.sort(((BeanList<T>) result).getActualList(), orderBy.toStringFormat());
}
}
}
@SuppressWarnings({"rawtypes"})
private void mergeCacheHitsToMap(BeanCollection<T> result) {
BeanMap map = (BeanMap)result;
ElPropertyValue property = mapProperty();
for (T bean : cacheBeans) {
map.internalPut(property.pathGet(bean), bean);
}
}
@Override
public List<T> getBeanCacheHits() {
OrderBy<T> orderBy = query.getOrderBy();
@@ -608,6 +627,33 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return cacheBeans;
}
@Override
public <K> Map<K, T> getBeanCacheHitsAsMap() {
OrderBy<T> orderBy = query.getOrderBy();
if (orderBy != null) {
beanDescriptor.sort(cacheBeans, orderBy.toStringFormat());
}
return cacheBeansToMap();
}
@SuppressWarnings("unchecked")
private <K> Map<K, T> cacheBeansToMap() {
ElPropertyValue property = mapProperty();
Map<K,T> map = new LinkedHashMap<>();
for (T bean : cacheBeans) {
map.put((K)property.pathGet(bean), bean);
}
return map;
}
private ElPropertyValue mapProperty() {
ElPropertyValue property = beanDescriptor.getElGetValue(query.getMapKey());
if (property == null) {
throw new IllegalStateException("Unknown map key property "+query.getMapKey());
}
return property;
}
@Override
public boolean getFromBeanCache() {
@@ -142,6 +142,11 @@ public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T>, DocQueryRequ
*/
List<T> getBeanCacheHits();
/**
* Return the bean cache hits for findMap (when all hits / no misses).
*/
<K> Map<K,T> getBeanCacheHitsAsMap();
/**
* Reset Bean cache mode AUTO - require explicit setting for bean cache use with findList().
*/