mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1211 - ENH: Support L2 cache complex natural keys include findList() queries
This commit is contained in:
@@ -85,7 +85,7 @@ public class TDSpiExpressionRequest implements SpiExpressionRequest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendInExpression(boolean not, Object[] bindValues) {
|
||||
public void appendInExpression(boolean not, List<Object> bindValues) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.querydefn;
|
||||
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.CacheMode;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
@@ -19,7 +20,7 @@ public class DefaultOrmQueryTest extends BaseTestCase {
|
||||
DefaultOrmQuery<Customer> q1 = (DefaultOrmQuery<Customer>) Ebean.find(Customer.class)
|
||||
.setForUpdate(true).where().eq("id", 42).query();
|
||||
|
||||
assertThat(q1.isExcludeBeanCache()).isTrue();
|
||||
assertThat(q1.getUseBeanCache()).isSameAs(CacheMode.OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.tests.batchload;
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.cache.ServerCache;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.cache.ServerCacheStatistics;
|
||||
import org.tests.model.basic.UUOne;
|
||||
import org.ebeantest.LoggedSqlCollector;
|
||||
@@ -18,6 +17,8 @@ import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class TestBatchLazyWithCacheHits extends BaseTestCase {
|
||||
|
||||
private ServerCache beanCache = server().getServerCacheManager().getBeanCache(UUOne.class);
|
||||
|
||||
private UUOne insert(String name) {
|
||||
UUOne one = new UUOne();
|
||||
one.setName("testBLWCH" + name);
|
||||
@@ -28,24 +29,17 @@ public class TestBatchLazyWithCacheHits extends BaseTestCase {
|
||||
@Test
|
||||
public void testOnCacheHit() {
|
||||
|
||||
ArrayList<UUOne> inserted = new ArrayList<>();
|
||||
String[] names = "A,B,C,D,E,F,G,H,I,J".split(",");
|
||||
for (String name : names) {
|
||||
inserted.add(insert(name));
|
||||
}
|
||||
ArrayList<UUOne> inserted = insertData();
|
||||
|
||||
ServerCacheManager serverCacheManager = Ebean.getDefaultServer().getServerCacheManager();
|
||||
ServerCache beanCache = serverCacheManager.getBeanCache(UUOne.class);
|
||||
beanCache.clear();
|
||||
beanCache.getStatistics(true); // Reset statistics - otherwise other tests will interfere
|
||||
clearCacheAndStatistics();
|
||||
|
||||
UUOne b = Ebean.find(UUOne.class, inserted.get(1).getId());
|
||||
assertNotNull(b);
|
||||
|
||||
UUOne b2 = Ebean.find(UUOne.class, inserted.get(1).getId());
|
||||
assertNotNull(b2);
|
||||
ServerCacheStatistics statistics = beanCache.getStatistics(true);
|
||||
assertEquals(statistics.getHitCount(), 1);
|
||||
|
||||
assertBeanCacheHits(1);
|
||||
|
||||
UUOne c = Ebean.find(UUOne.class)
|
||||
.where().idEq(inserted.get(2).getId())
|
||||
@@ -55,9 +49,9 @@ public class TestBatchLazyWithCacheHits extends BaseTestCase {
|
||||
UUOne c2 = Ebean.find(UUOne.class)
|
||||
.where().idEq(inserted.get(2).getId())
|
||||
.findOne();
|
||||
|
||||
assertNotNull(c2);
|
||||
statistics = beanCache.getStatistics(true);
|
||||
assertEquals(statistics.getHitCount(), 1);
|
||||
assertBeanCacheHits(1);
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
@@ -76,13 +70,33 @@ public class TestBatchLazyWithCacheHits extends BaseTestCase {
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
System.out.println("sql:" + sql);
|
||||
|
||||
// batch lazy loading into cache
|
||||
assertThat(sql).hasSize(2);
|
||||
assertThat(sql.get(0)).contains("from uuone t0 where t0.name like ");
|
||||
platformAssertIn(sql.get(1), "from uuone t0 where t0.id");
|
||||
|
||||
statistics = beanCache.getStatistics(true);
|
||||
assertThat(statistics.getSize()).isGreaterThan(3);
|
||||
// not lazy loading into bean cache
|
||||
int size = beanCache.getStatistics(true).getSize();
|
||||
assertThat(size).isEqualTo(2);
|
||||
}
|
||||
|
||||
private void assertBeanCacheHits(int hits) {
|
||||
ServerCacheStatistics statistics = beanCache.getStatistics(true);
|
||||
assertEquals(statistics.getHitCount(), hits);
|
||||
}
|
||||
|
||||
private void clearCacheAndStatistics() {
|
||||
|
||||
beanCache.clear();
|
||||
beanCache.getStatistics(true);
|
||||
}
|
||||
|
||||
private ArrayList<UUOne> insertData() {
|
||||
ArrayList<UUOne> inserted = new ArrayList<>();
|
||||
String[] names = "A,B,C,D,E,F,G,H,I,J".split(",");
|
||||
for (String name : names) {
|
||||
inserted.add(insert(name));
|
||||
}
|
||||
return inserted;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.tests.model.basic.cache;
|
||||
|
||||
import io.ebean.annotation.Cache;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* Cached bean for testing caching implementation.
|
||||
*/
|
||||
@Cache(naturalKey = {"store","sku"})
|
||||
@Entity
|
||||
@Table(name = "o_cached_natkey")
|
||||
public class OCachedNatKeyBean {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
String store;
|
||||
|
||||
String sku;
|
||||
|
||||
String description;
|
||||
|
||||
OCachedNatKeyBean(String store, String sku) {
|
||||
this.store = store;
|
||||
this.sku = sku;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getStore() {
|
||||
return store;
|
||||
}
|
||||
|
||||
public void setStore(String store) {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public String getSku() {
|
||||
return sku;
|
||||
}
|
||||
|
||||
public void setSku(String sku) {
|
||||
this.sku = sku;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.tests.model.basic.cache;
|
||||
|
||||
import io.ebean.annotation.Cache;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* Cached bean for compound natural key.
|
||||
*/
|
||||
@Cache(naturalKey = {"store","code","sku"})
|
||||
@Entity
|
||||
@Table(name = "o_cached_natkey3")
|
||||
public class OCachedNatKeyBean3 {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
String store;
|
||||
|
||||
int code;
|
||||
|
||||
String sku;
|
||||
|
||||
String description;
|
||||
|
||||
OCachedNatKeyBean3(String store, int code, String sku) {
|
||||
this.store = store;
|
||||
this.code = code;
|
||||
this.sku = sku;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getStore() {
|
||||
return store;
|
||||
}
|
||||
|
||||
public void setStore(String store) {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public String getSku() {
|
||||
return sku;
|
||||
}
|
||||
|
||||
public void setSku(String sku) {
|
||||
this.sku = sku;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
package org.tests.model.basic.cache;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.cache.ServerCache;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.cache.ServerCacheStatistics;
|
||||
import org.ebeantest.LoggedSqlCollector;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestCacheViaComplexNaturalKey extends BaseTestCase {
|
||||
|
||||
private ServerCache beanCache = cacheManager().getBeanCache(OCachedNatKeyBean.class);
|
||||
private ServerCache natKeyCache = cacheManager().getNaturalKeyCache(OCachedNatKeyBean.class);
|
||||
|
||||
private static boolean loadOnce;
|
||||
|
||||
private ServerCacheManager cacheManager() {
|
||||
return server().getServerCacheManager();
|
||||
}
|
||||
|
||||
private static synchronized void insertSome() {
|
||||
if (!loadOnce) {
|
||||
Ebean.find(OCachedNatKeyBean.class).delete();
|
||||
|
||||
List<String> stores = new ArrayList<>(Arrays.asList("abc", "def"));
|
||||
for (String store : stores) {
|
||||
List<String> skus = new ArrayList<>(Arrays.asList("1", "2", "3", "4"));
|
||||
for (String sku : skus) {
|
||||
saveBean(store, sku);
|
||||
}
|
||||
}
|
||||
loadOnce = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void saveBean(String abc, String sku) {
|
||||
Ebean.save(new OCachedNatKeyBean(abc, sku));
|
||||
}
|
||||
|
||||
private void clearCacheAndStatistics() {
|
||||
Ebean.getServerCacheManager().clearAll();
|
||||
clearStatistics();
|
||||
}
|
||||
|
||||
private void clearStatistics() {
|
||||
beanCache.getStatistics(true);
|
||||
natKeyCache.getStatistics(true);
|
||||
}
|
||||
|
||||
private void assertNaturalKeyHitMiss(int expectedHit, int expectedMiss) {
|
||||
ServerCacheStatistics stats = natKeyCache.getStatistics(true);
|
||||
assertHitMiss(expectedHit, expectedMiss, stats);
|
||||
}
|
||||
|
||||
private void assertBeanCacheHitMiss(int expectedHit, int expectedMiss) {
|
||||
ServerCacheStatistics stats = beanCache.getStatistics(true);
|
||||
assertHitMiss(expectedHit, expectedMiss, stats);
|
||||
}
|
||||
|
||||
private void assertHitMiss(int expectedHit, int expectedMiss, ServerCacheStatistics stats) {
|
||||
assertThat(stats.getHitCount()).isEqualTo(expectedHit);
|
||||
assertThat(stats.getMissCount()).isEqualTo(expectedMiss);
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
insertSome();
|
||||
clearCacheAndStatistics();
|
||||
}
|
||||
|
||||
private void loadSomeIntoCache() {
|
||||
|
||||
Ebean.find(OCachedNatKeyBean.class)
|
||||
.setLoadBeanCache(true)
|
||||
.where().le("sku", "2")
|
||||
.findList();
|
||||
|
||||
clearStatistics();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findList_inClause_someHits() {
|
||||
|
||||
setup();
|
||||
loadSomeIntoCache();
|
||||
|
||||
String storeId = "abc";
|
||||
List<String> skus = new ArrayList<>(Arrays.asList("1", "2", "3"));
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
List<OCachedNatKeyBean> list = Ebean.find(OCachedNatKeyBean.class)
|
||||
.where()
|
||||
.eq("store", storeId)
|
||||
.in("sku", skus)
|
||||
.setUseCache(true)
|
||||
.orderBy("sku desc")
|
||||
.findList();
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
assertThat(sql).hasSize(1);
|
||||
if (isH2()) {
|
||||
// in clause with only 1 bind param - (sku=3 ... we got hits on sku 1 and 2)
|
||||
assertThat(sql.get(0)).contains("from o_cached_natkey t0 where t0.store = ? and t0.sku in (? ) order by t0.sku desc; --bind(abc,Array[1]={3})");
|
||||
}
|
||||
|
||||
assertThat(list).hasSize(3);
|
||||
|
||||
assertNaturalKeyHitMiss(2, 1);
|
||||
assertBeanCacheHitMiss(2, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findList_inClause_allHits() {
|
||||
|
||||
setup();
|
||||
loadSomeIntoCache();
|
||||
|
||||
String storeId = "abc";
|
||||
List<String> skus = new ArrayList<>(Arrays.asList("1", "2"));
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
List<OCachedNatKeyBean> list = Ebean.find(OCachedNatKeyBean.class)
|
||||
.where()
|
||||
.eq("store", storeId)
|
||||
.in("sku", skus)
|
||||
.setUseCache(true)
|
||||
.orderBy("sku desc")
|
||||
.findList();
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
|
||||
// no SQL - all beans from cache
|
||||
assertThat(sql).isEmpty();
|
||||
|
||||
assertThat(list).hasSize(2);
|
||||
assertNaturalKeyHitMiss(2, 0);
|
||||
assertBeanCacheHitMiss(2, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findList_inClause_noHits() {
|
||||
|
||||
setup();
|
||||
loadSomeIntoCache();
|
||||
|
||||
String storeId = "abc";
|
||||
List<String> skus = new ArrayList<>(Arrays.asList("3", "4"));
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
List<OCachedNatKeyBean> list = Ebean.find(OCachedNatKeyBean.class)
|
||||
.where()
|
||||
.eq("store", storeId)
|
||||
.in("sku", skus)
|
||||
.setUseCache(true)
|
||||
.orderBy("sku desc")
|
||||
.findList();
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
assertThat(sql).hasSize(1);
|
||||
if (isH2()) {
|
||||
// in clause with 2 bind params as we got not hits on the cache
|
||||
assertThat(sql.get(0)).contains("from o_cached_natkey t0 where t0.store = ? and t0.sku in (?, ? ) order by t0.sku desc; --bind(abc,Array[2]={3,4})");
|
||||
}
|
||||
|
||||
assertThat(list).hasSize(2);
|
||||
assertNaturalKeyHitMiss(0, 2);
|
||||
assertBeanCacheHitMiss(0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hit() {
|
||||
|
||||
setup();
|
||||
loadSomeIntoCache();
|
||||
|
||||
// simple case - no IN clause
|
||||
OCachedNatKeyBean hit = Ebean.find(OCachedNatKeyBean.class)
|
||||
.where()
|
||||
.eq("store", "abc")
|
||||
.eq("sku", "2")
|
||||
.findOne();
|
||||
|
||||
assertThat(hit).isNotNull();
|
||||
|
||||
assertNaturalKeyHitMiss(1, 0);
|
||||
assertBeanCacheHitMiss(1, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void miss() {
|
||||
|
||||
setup();
|
||||
|
||||
OCachedNatKeyBean miss = Ebean.find(OCachedNatKeyBean.class)
|
||||
.where()
|
||||
.eq("store", "def")
|
||||
.eq("sku", "4")
|
||||
.findOne();
|
||||
|
||||
assertThat(miss).isNotNull();
|
||||
|
||||
// miss on natural key
|
||||
assertNaturalKeyHitMiss(0, 1);
|
||||
|
||||
// no activity against bean cache
|
||||
assertBeanCacheHitMiss(0, 0);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void explicitUseCacheFalse_expect_noUseOfCache() {
|
||||
|
||||
setup();
|
||||
|
||||
OCachedNatKeyBean miss = Ebean.find(OCachedNatKeyBean.class)
|
||||
.where()
|
||||
.eq("store", "def")
|
||||
.eq("sku", "4")
|
||||
.setUseCache(false) // explicitly not use cache
|
||||
.findOne();
|
||||
|
||||
assertThat(miss).isNotNull();
|
||||
|
||||
// no activity against either cache
|
||||
assertNaturalKeyHitMiss(0, 0);
|
||||
assertBeanCacheHitMiss(0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
package org.tests.model.basic.cache;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.cache.ServerCache;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.cache.ServerCacheStatistics;
|
||||
import org.ebeantest.LoggedSqlCollector;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestCacheViaComplexNaturalKey3 extends BaseTestCase {
|
||||
|
||||
private ServerCache beanCache = cacheManager().getBeanCache(OCachedNatKeyBean3.class);
|
||||
private ServerCache natKeyCache = cacheManager().getNaturalKeyCache(OCachedNatKeyBean3.class);
|
||||
|
||||
private static boolean loadOnce;
|
||||
|
||||
private ServerCacheManager cacheManager() {
|
||||
return server().getServerCacheManager();
|
||||
}
|
||||
|
||||
private static synchronized void insertSome() {
|
||||
if (!loadOnce) {
|
||||
Ebean.find(OCachedNatKeyBean3.class).delete();
|
||||
|
||||
List<String> stores = new ArrayList<>(Arrays.asList("abc", "def"));
|
||||
for (String store : stores) {
|
||||
List<String> skus = new ArrayList<>(Arrays.asList("1", "2", "3"));
|
||||
for (String sku : skus) {
|
||||
int[] codes = {1000,1001,1002,1003,1004};
|
||||
for (int code : codes) {
|
||||
saveBean(store, code, sku);
|
||||
}
|
||||
}
|
||||
}
|
||||
loadOnce = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void saveBean(String store, int code, String sku) {
|
||||
Ebean.save(new OCachedNatKeyBean3(store, code, sku));
|
||||
}
|
||||
|
||||
private void clearCacheAndStatistics() {
|
||||
Ebean.getServerCacheManager().clearAll();
|
||||
clearStatistics();
|
||||
}
|
||||
|
||||
private void clearStatistics() {
|
||||
beanCache.getStatistics(true);
|
||||
natKeyCache.getStatistics(true);
|
||||
}
|
||||
|
||||
private void assertNaturalKeyHitMiss(int expectedHit, int expectedMiss) {
|
||||
ServerCacheStatistics stats = natKeyCache.getStatistics(true);
|
||||
assertHitMiss(expectedHit, expectedMiss, stats);
|
||||
}
|
||||
|
||||
private void assertBeanCacheHitMiss(int expectedHit, int expectedMiss) {
|
||||
ServerCacheStatistics stats = beanCache.getStatistics(true);
|
||||
assertHitMiss(expectedHit, expectedMiss, stats);
|
||||
}
|
||||
|
||||
private void assertHitMiss(int expectedHit, int expectedMiss, ServerCacheStatistics stats) {
|
||||
assertThat(stats.getHitCount()).isEqualTo(expectedHit);
|
||||
assertThat(stats.getMissCount()).isEqualTo(expectedMiss);
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
insertSome();
|
||||
clearCacheAndStatistics();
|
||||
}
|
||||
|
||||
private void loadSomeIntoCache() {
|
||||
|
||||
Ebean.find(OCachedNatKeyBean3.class)
|
||||
.setLoadBeanCache(true)
|
||||
.where()
|
||||
.ge("sku", "2")
|
||||
.eq("store", "def")
|
||||
.ge("code", 1001)
|
||||
.findList();
|
||||
|
||||
clearStatistics();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findList_inClause_someHits() {
|
||||
|
||||
setup();
|
||||
loadSomeIntoCache();
|
||||
|
||||
|
||||
List<Integer> codes = new ArrayList<>(Arrays.asList(1001, 1000, 1002, 1003));
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
List<OCachedNatKeyBean3> list = Ebean.find(OCachedNatKeyBean3.class)
|
||||
.where()
|
||||
.eq("store", "def")
|
||||
.in("code", codes)
|
||||
.eq("sku", "2")
|
||||
.setUseCache(true)
|
||||
.order().desc("sku")
|
||||
.order().asc("code")
|
||||
.findList();
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
assertThat(sql).hasSize(1);
|
||||
if (isH2()) {
|
||||
// in clause with only 1 bind param - (sku=3 ... we got hits on sku 1 and 2)
|
||||
assertThat(sql.get(0)).contains("from o_cached_natkey3 t0 where t0.store = ? and t0.code in (? ) and t0.sku = ? order by t0.sku desc, t0.code; --bind(def,Array[1]={1000},2)");
|
||||
}
|
||||
|
||||
assertThat(list).hasSize(4);
|
||||
|
||||
assertNaturalKeyHitMiss(3, 1);
|
||||
assertBeanCacheHitMiss(3, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findList_inClause_allHits() {
|
||||
|
||||
setup();
|
||||
loadSomeIntoCache();
|
||||
|
||||
List<String> skus = new ArrayList<>(Arrays.asList("2", "3"));
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
List<OCachedNatKeyBean3> list = Ebean.find(OCachedNatKeyBean3.class)
|
||||
.where()
|
||||
.eq("store", "def")
|
||||
.in("sku", skus)
|
||||
.eq("code", 1001)
|
||||
.setUseCache(true)
|
||||
.orderBy("sku desc")
|
||||
.findList();
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
|
||||
// no SQL - all beans from cache
|
||||
assertThat(sql).isEmpty();
|
||||
|
||||
assertThat(list).hasSize(2);
|
||||
assertNaturalKeyHitMiss(2, 0);
|
||||
assertBeanCacheHitMiss(2, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findList_inClause_noHits() {
|
||||
|
||||
setup();
|
||||
loadSomeIntoCache();
|
||||
|
||||
String storeId = "abc";
|
||||
List<String> skus = new ArrayList<>(Arrays.asList("3", "2", "4"));
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
List<OCachedNatKeyBean3> list = Ebean.find(OCachedNatKeyBean3.class)
|
||||
.where()
|
||||
.eq("store", storeId)
|
||||
.in("sku", skus)
|
||||
.eq("code", 1001)
|
||||
.setUseCache(true)
|
||||
.orderBy("sku desc")
|
||||
.findList();
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
assertThat(sql).hasSize(1);
|
||||
if (isH2()) {
|
||||
// in clause with 2 bind params as we got not hits on the cache
|
||||
assertThat(sql.get(0)).contains("from o_cached_natkey3 t0 where t0.store = ? and t0.sku in (?, ?, ? ) and t0.code = ? order by t0.sku desc; --bind(abc,Array[3]={3,2,4},1001)");
|
||||
}
|
||||
|
||||
assertThat(list).hasSize(2);
|
||||
assertNaturalKeyHitMiss(0, 3);
|
||||
assertBeanCacheHitMiss(0, 0);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void hit() {
|
||||
|
||||
setup();
|
||||
loadSomeIntoCache();
|
||||
|
||||
// simple case - no IN clause
|
||||
OCachedNatKeyBean3 hit = Ebean.find(OCachedNatKeyBean3.class)
|
||||
.where()
|
||||
.eq("store", "def")
|
||||
.eq("sku", "2")
|
||||
.eq("code", 1002)
|
||||
.findOne();
|
||||
|
||||
assertThat(hit).isNotNull();
|
||||
|
||||
assertNaturalKeyHitMiss(1, 0);
|
||||
assertBeanCacheHitMiss(1, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void miss() {
|
||||
|
||||
setup();
|
||||
|
||||
OCachedNatKeyBean3 miss = Ebean.find(OCachedNatKeyBean3.class)
|
||||
.where()
|
||||
.eq("store", "abc")
|
||||
.eq("sku", "2")
|
||||
.eq("code", 1000)
|
||||
.findOne();
|
||||
|
||||
assertThat(miss).isNotNull();
|
||||
|
||||
// miss on natural key
|
||||
assertNaturalKeyHitMiss(0, 1);
|
||||
|
||||
// no activity against bean cache
|
||||
assertBeanCacheHitMiss(0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void explicitUseCacheFalse_expect_noUseOfCache() {
|
||||
|
||||
setup();
|
||||
|
||||
OCachedNatKeyBean3 miss = Ebean.find(OCachedNatKeyBean3.class)
|
||||
.where()
|
||||
.eq("store", "abc")
|
||||
.eq("sku", "2")
|
||||
.eq("code", 1000)
|
||||
.setUseCache(false) // explicitly not use cache
|
||||
.findOne();
|
||||
|
||||
assertThat(miss).isNotNull();
|
||||
|
||||
// no activity against either cache
|
||||
assertNaturalKeyHitMiss(0, 0);
|
||||
assertBeanCacheHitMiss(0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user