diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java index 5a6ae2217..3f2e97893 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java @@ -81,6 +81,11 @@ public interface SpiQuery extends Query, SpiQueryFetch, TxnProfileEventCod */ ID_LIST(FIND_ID_LIST, "findIds"), + /** + * Find exists. + */ + EXISTS(FIND_EXISTS, "exists"), + /** * Find single attribute. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/TxnProfileEventCodes.java b/ebean-core/src/main/java/io/ebeaninternal/api/TxnProfileEventCodes.java index 231d38296..c4d1ea0be 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/TxnProfileEventCodes.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/TxnProfileEventCodes.java @@ -26,6 +26,7 @@ public interface TxnProfileEventCodes { String FIND_MANY = "fm"; String FIND_ITERATE = "fe"; String FIND_ID_LIST = "fi"; + String FIND_EXISTS = "ex"; String FIND_ATTRIBUTE = "fa"; String FIND_COUNT = "fc"; String FIND_SUBQUERY = "fs"; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index 0e293d37d..939421be4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -1296,7 +1296,12 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { @Override public boolean exists(Query ormQuery, Transaction transaction) { Query ormQueryCopy = ormQuery.copy().setMaxRows(1); - SpiOrmQueryRequest request = createQueryRequest(Type.ID_LIST, ormQueryCopy, transaction); + SpiOrmQueryRequest request = createQueryRequest(Type.EXISTS, ormQueryCopy, transaction); + List ids = request.getFromQueryCache(); + if (ids != null) { + return !ids.isEmpty(); + } + try { request.initTransIfRequired(); return !request.findIds().isEmpty(); diff --git a/ebean-test/src/test/java/org/tests/cache/TestQueryCache.java b/ebean-test/src/test/java/org/tests/cache/TestQueryCache.java index f70bc44c7..f127101f9 100644 --- a/ebean-test/src/test/java/org/tests/cache/TestQueryCache.java +++ b/ebean-test/src/test/java/org/tests/cache/TestQueryCache.java @@ -16,7 +16,10 @@ import java.util.List; import java.util.function.Consumer; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; public class TestQueryCache extends BaseTestCase { @@ -126,15 +129,52 @@ public class TestQueryCache extends BaseTestCase { // and now, ensure that we hit the database LoggedSql.start(); int count2 = DB.find(EColAB.class) - .setUseQueryCache(CacheMode.OFF) - .where() - .eq("columnB", "count") - .findCount(); + .setUseQueryCache(CacheMode.OFF) + .where() + .eq("columnB", "count") + .findCount(); assertThat(count2).isEqualTo(count1); sql = LoggedSql.stop(); assertThat(sql).hasSize(1); } + @Test + public void exists() { + + new EColAB("06", "exists").save(); + new EColAB("07", "exists").save(); + + LoggedSql.start(); + + boolean exists0 = DB.find(EColAB.class) + .setUseQueryCache(CacheMode.ON) + .where() + .eq("columnB", "exists") + .exists(); + + boolean exists1 = DB.find(EColAB.class) + .setUseQueryCache(CacheMode.ON) + .where() + .eq("columnB", "exists") + .exists(); + + List sql = LoggedSql.stop(); + + assertThat(exists0).isEqualTo(exists1); + assertThat(sql).hasSize(1); + + // and now, ensure that we hit the database + LoggedSql.start(); + boolean exists2 = DB.find(EColAB.class) + .setUseQueryCache(CacheMode.OFF) + .where() + .eq("columnB", "exists") + .exists(); + assertThat(exists2).isEqualTo(exists1); + sql = LoggedSql.stop(); + assertThat(sql).hasSize(1); + } + @Test public void findCountDifferentQueries() {