#1864 - L2 cache miss for natural key property of type UUID

This commit is contained in:
rob bygrave
2019-11-17 17:06:38 +13:00
parent 9b0dd2b0c4
commit c2a30f786f
6 changed files with 122 additions and 14 deletions
@@ -8,7 +8,7 @@ public interface NaturalKeyEntry {
/**
* Return the natural cache key (String concatenation of values).
*/
Object key();
String key();
/**
* Return the inValue (used to remove from IN clause of original query).
@@ -14,7 +14,7 @@ import java.util.Map;
class NaturalKeyEntryBasic implements NaturalKeyEntry {
private final Map<String,Object> map = new HashMap<>();
private final Object key;
private final String key;
private Object inValue;
/**
@@ -57,12 +57,12 @@ class NaturalKeyEntryBasic implements NaturalKeyEntry {
}
}
private Object calculateKey(BeanNaturalKey naturalKey) {
private String calculateKey(BeanNaturalKey naturalKey) {
return naturalKey.calculateKey(map);
}
@Override
public Object key() {
public String key() {
return key;
}
@@ -2,19 +2,21 @@ package io.ebeaninternal.api;
class NaturalKeyEntrySimple implements NaturalKeyEntry {
private final Object key;
private final String key;
private final Object val;
NaturalKeyEntrySimple(Object key) {
this.key = key;
NaturalKeyEntrySimple(Object val) {
this.key = val.toString();
this.val = val;
}
@Override
public Object key() {
public String key() {
return key;
}
@Override
public Object getInValue() {
return key;
return val;
}
}
@@ -66,11 +66,7 @@ public class BeanNaturalKey {
*
* @param map The bind values for the properties.
*/
public Object calculateKey(Map<String, Object> map) {
if (naturalKey.length == 1) {
return map.get(naturalKey[0]);
}
public String calculateKey(Map<String, Object> map) {
StringBuilder sb = new StringBuilder();
for (BeanProperty prop : props) {
sb.append(prop.naturalKeyVal(map)).append(";");
@@ -0,0 +1,28 @@
package org.tests.model.basic.cache;
import io.ebean.annotation.Cache;
import javax.persistence.Entity;
import java.util.UUID;
@Cache(naturalKey = "uid")
@Entity
public class OCachedNkeyUid extends OCacheBase {
private UUID uid;
private String other;
public OCachedNkeyUid(UUID uid, String other) {
this.uid = uid;
this.other = other;
}
public UUID getUid() {
return uid;
}
public String getOther() {
return other;
}
}
@@ -0,0 +1,82 @@
package org.tests.model.basic.cache;
import io.ebean.BaseTestCase;
import io.ebean.DB;
import io.ebean.cache.ServerCacheStatistics;
import org.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import java.util.List;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
public class TestNatKeyUid extends BaseTestCase {
private static boolean seededData;
private static UUID one = UUID.randomUUID();
private static UUID two = UUID.randomUUID();
private ServerCacheStatistics appStats() {
return getBeanCacheStats(OCachedNkeyUid.class, true);
}
@Test
public void test_findOne() {
setupData();
clearAllL2Cache();
OCachedNkeyUid found1 = findOne();
assertNotNull(found1);
assertThat(appStats().getHitCount()).isEqualTo(0);
found1 = findOne();
assertNotNull(found1);
assertThat(appStats().getHitCount()).isEqualTo(1);
}
private OCachedNkeyUid findOne() {
return DB.find(OCachedNkeyUid.class)
.where()
.eq("uid", one)
.findOne();
}
@Test
public void test_findMany() {
setupData();
clearAllL2Cache();
List<OCachedNkeyUid> result = findMany();
assertThat(result).hasSize(2);
assertThat(appStats().getHitCount()).isEqualTo(0);
LoggedSqlCollector.start();
result = findMany();
assertThat(result).hasSize(2);
assertThat(appStats().getHitCount()).isEqualTo(2);
final List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).as("Expected hit cache, no sql").isEmpty();
}
private List<OCachedNkeyUid> findMany() {
return DB.find(OCachedNkeyUid.class)
.setUseCache(true)
.where()
.in("uid", one, two)
.findList();
}
private void setupData() {
if (!seededData) {
seededData = true;
new OCachedNkeyUid(one, "o1").save();
new OCachedNkeyUid(two, "o2").save();
}
}
}