package io.ebeaninternal.server.core; import io.ebean.BaseTestCase; import io.ebean.Ebean; import io.ebean.FetchConfig; import io.ebean.Query; import io.ebeaninternal.server.querydefn.DefaultOrmQuery; import io.ebeaninternal.server.querydefn.OrmQueryDetail; import org.tests.model.basic.Order; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; public class DefaultServer_createOrmQueryRequestTest extends BaseTestCase { Query<Order> query() { return server().find(Order.class); } OrmQueryRequest<Order> queryRequest(Query<Order> query) { return OrmQueryRequestTestHelper.queryRequest(query); } OrmQueryDetail detail(Query<Order> query) { return queryRequest(query).getQuery().getDetail(); } @Test public void when_empty_then_same() { assertSame(detail(query()), detail(query())); } @Test public void select_all_then_same() { assertSame(detail(query().select("*")), detail(query().select("*"))); } @Test public void when_propertiesInOrder_then_same() { assertSame(detail(query().select("id,name")), detail(query().select("id,name"))); } @Test public void when_propertiesInDifferentOrder_then_different() { assertDifferent(detail(query().select("id,name")), detail(query().select("name, id"))); // but same from autotune perspective assertThat(detail(query().select("id,name")).isAutoTuneEqual(detail(query().select("name, id")))).isTrue(); } @Test public void when_additional_fetch_then_different() { assertDifferent(detail(query().select("id,name")), detail(query().select("id,name").fetch("details"))); } @Test public void when_same_fetch_then_same() { assertSame(detail(query().select("id,name").fetch("details")), detail(query().select("id,name").fetch("details"))); } @Test public void when_fetch_order_different_then_different() { assertDifferent(detail(query().select("id,name").fetch("details").fetch("customer")), detail(query().select("id,name").fetch("customer").fetch("details"))); } @Test public void when_extra_queryFetchToMany_then_same() { assertDifferent(detail(query().select("id,name").fetch("customer")), detail(query().select("id,name").fetch("customer").fetch("details", new FetchConfig().query()))); } @Test public void when_extra_queryToOne_fetch_then_different() { // with the fetch of customer the foreign key must be added to the root query assertDifferent(detail(query().select("id,name")), detail(query().select("id,name").fetch("customer", new FetchConfig().query()))); } @Test public void when_additional_fetch_V2_then_different() { assertDifferent(detail(query().select("id,name")), detail(query().select("id,name").fetch("customer", "id"))); } @Test public void when_fetchConfig_then_differentPlan() throws Exception { DefaultOrmQuery<Order> query1 = (DefaultOrmQuery<Order>) Ebean.find(Order.class) .select("status, shipDate") .fetch("details", "orderQty, unitPrice", new FetchConfig().query()) .fetch("details.product", "sku, name"); DefaultOrmQuery<Order> query2 = (DefaultOrmQuery<Order>) Ebean.find(Order.class) .select("status, shipDate") .fetch("details", "orderQty, unitPrice") .fetch("details.product", "sku, name"); assertDifferent(detail(query1), detail(query2)); } @Test public void testJoinOrder_when_fetchJoins_expect_detailJoinsPreserveOrder() { Query<Order> query = Ebean.find(Order.class) .select("status, orderDate") .fetch("customer", "name") .fetch("details"); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer", "details"); } @Test public void testJoinOrder_when_fetchJoinsAndWhere_expect_fetchJoinsOnlyInFetchPaths() { Query<Order> query = Ebean.find(Order.class) .select("status, orderDate") .fetch("details") .where().eq("customer.name", "rob").query(); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("details"); } @Test public void testJoinOrder_when_queryFetch_expect_getFetchPaths_doesNotIncludeQueryJoin() { Query<Order> query = Ebean.find(Order.class) .select("status, orderDate") .fetch("customer", "name") .fetch("details", new FetchConfig().query()); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer"); } @Test public void testJoinOrder_when_queryFetch_expect_getFetchPaths_doesNotIncludeQueryJoin_via_fetchQuery() { Query<Order> query = Ebean.find(Order.class) .select("status, orderDate") .fetch("customer", "name") .fetchQuery("details"); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer"); } @Test public void testJoinOrder_when_lazyFetch_expect_getFetchPaths_doesNotIncludeQueryJoin() { Query<Order> query = Ebean.find(Order.class) .select("status, orderDate") .fetch("customer", "name") .fetch("details", new FetchConfig().lazy()); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer"); } @Test public void testJoinOrder_when_lazyFetch_expect_getFetchPaths_doesNotIncludeQueryJoin_via_fetchLazy() { Query<Order> query = Ebean.find(Order.class) .select("status, orderDate") .fetch("customer", "name") .fetchLazy("details"); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer"); } @Test public void testJoinOrder_when_lazyFetchAndHasChildren_expect_getFetchPaths_doesNotIncludeJoinOrChild() { Query<Order> query = Ebean.find(Order.class) .select("status, orderDate") .fetch("customer", "name") .fetch("details", new FetchConfig().lazy()) .fetch("details.product"); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer"); } @Test public void testJoinOrder_when_fetchMany_expect_getFetchPaths_containsAllInOrder() { Query<Order> query = Ebean.find(Order.class) .select("status, orderDate") .fetch("details") .fetch("details.product") .fetch("customer", "name"); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("details", "details.product", "customer"); } @Test public void testJoinOrder_when_queryJoin_expect_getFetchPaths_excludesQueryJoinAndChildren() { Query<Order> query = Ebean.find(Order.class) .select("status, orderDate") .fetch("details", new FetchConfig().query()) .fetch("details.product") .fetch("customer", "name"); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer"); } @Test public void test_removeJoinToMany_when_multipleManyPaths() { Query<Order> query = Ebean.find(Order.class) .fetch("details") .fetch("details.product") .fetch("customer") .fetch("customer.contacts"); // second many path OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("details", "details.product", "customer"); } @Test public void test_removeAllJoinToMany_when_firstRow() { Query<Order> query = Ebean.find(Order.class) .setFirstRow(1) .fetch("details") // many path .fetch("details.product") .fetch("customer") .fetch("customer.contacts"); // many path OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer"); } @Test public void test_removeAllJoinToMany_when_maxRows() { Query<Order> query = Ebean.find(Order.class) .setMaxRows(1) .fetch("details") // many path .fetch("details.product") .fetch("customer") .fetch("customer.contacts"); // many path OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer"); } @Test public void test_removeJoinToMany_when_filterMany() { Query<Order> query = Ebean.find(Order.class) .fetch("details") .fetch("details.product") .fetch("customer") .fetch("customer.contacts") .filterMany("details").eq("orderQuantity", 10) .query(); OrmQueryRequest<Order> queryRequest = queryRequest(query); OrmQueryDetail detail = queryRequest.getQuery().getDetail(); assertThat(detail.getFetchPaths()).containsExactly("customer", "customer.contacts"); } private void assertSame(OrmQueryDetail detail1, OrmQueryDetail detail2) { assertThat(detail1.isSameByPlan(detail2)).isTrue(); assertThat(detail1.queryPlanHash()).isEqualTo(detail2.queryPlanHash()); } private void assertDifferent(OrmQueryDetail detail1, OrmQueryDetail detail2) { assertThat(detail1.isSameByPlan(detail2)).isFalse(); assertThat(detail1.queryPlanHash()).isNotEqualTo(detail2.queryPlanHash()); } }