#919 - io.ebean package initial

This commit is contained in:
Rob Bygrave
2016-12-11 23:23:22 +13:00
parent 5821dc96b9
commit 971e2dc91b
2134 changed files with 10721 additions and 8652 deletions
@@ -0,0 +1,173 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.PagedList;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Ebean adds order by clause if none provided when using both first rows and max rows.
*/
public class TestAddOrderByWithFirstRowsMaxRows extends BaseTestCase {
@Test
public void test_firstRows() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Order.class)
.setFirstRow(3)
.orderBy().asc("id")
.findList();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(loggedSql.get(0)).contains("order by t0.id");
}
@Test
public void test_maxRows() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Order.class)
.setMaxRows(10)
.findList();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(loggedSql.get(0)).contains("order by t0.id");
}
@Test
public void test_firstRowsMaxRows() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Order.class)
.setFirstRow(3)
.setMaxRows(10)
.orderBy().asc("id")
.findList();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(loggedSql.get(0)).contains("order by t0.id");
}
@Test
public void test_maxRows1() {
ResetBasicData.reset();
LoggedSqlCollector.start();
// maxRows 1 with no first rows means Ebean does not automatically
// add the order by id to the query
Ebean.find(Order.class)
.setMaxRows(1)
.findList();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(loggedSql.get(0)).doesNotContain("order by t0.id");
}
@Test
public void test_pagingOne() {
ResetBasicData.reset();
LoggedSqlCollector.start();
PagedList<Order> pagedList =
Ebean.find(Order.class)
.setMaxRows(10)
.findPagedList();
pagedList.getList();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(loggedSql.get(0)).contains("order by t0.id");
}
@Test
public void test_pagingTwo() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Order.class)
.setFirstRow(10)
.setMaxRows(10)
.findPagedList()
.getList();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(loggedSql.get(0)).contains("order by t0.id");
}
@Test
public void test_pagingAppendToExistingOrderBy() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Order.class)
.order().asc("orderDate")
.setMaxRows(10)
.findPagedList()
.getList();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(loggedSql.get(0)).contains("order by t0.order_date, t0.id");
}
@Test
public void test_pagingExistingOrderByWithId() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Order.class)
.order().asc("orderDate")
.order().desc("id")
.setMaxRows(10)
.findPagedList()
.getList();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(loggedSql.get(0)).contains("order by t0.order_date, t0.id desc");
}
}
@@ -0,0 +1,72 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import io.ebean.bean.ObjectGraphNode;
import io.ebean.bean.ObjectGraphOrigin;
import io.ebeaninternal.api.SpiQuery;
import org.tests.model.basic.Address;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
public class TestAutofetchTuneWithJoin extends BaseTestCase {
@Test
public void test() {
runQuery();
collectUsage();
}
private void runQuery() {
ResetBasicData.reset();
Query<Order> q = Ebean.find(Order.class)
.setAutoTune(true)
//.fetch("customer")
//.fetch("customer.contacts")
.where().lt("id", 3).query();
List<Order> list = q.findList();
for (Order order : list) {
order.getOrderDate();
order.getShipDate();
// order.setShipDate(new Date(System.currentTimeMillis()));
Customer customer = order.getCustomer();
customer.getName();
Address shippingAddress = customer.getShippingAddress();
if (shippingAddress != null) {
shippingAddress.getLine1();
shippingAddress.getCity();
}
// customer.getContacts()
}
SpiQuery<?> sq = (SpiQuery<?>) q;
ObjectGraphNode parentNode = sq.getParentNode();
ObjectGraphOrigin origin = parentNode.getOriginQueryPoint();
// MetaAutoFetchStatistic metaAutoFetchStatistic =
// ((DefaultOrmQuery<?>)q).getMetaAutoFetchStatistic();
// if (metaAutoFetchStatistic != null) {
// List<NodeUsageStats> nodeUsageStats =
// metaAutoFetchStatistic.getNodeUsageStats();
// System.out.println(nodeUsageStats);
// List<QueryStats> queryStats = metaAutoFetchStatistic.getQueryStats();
// System.out.println(queryStats);
// }
}
private static void collectUsage() {
Ebean.getDefaultServer().getAutoTune().collectProfiling();
}
}
@@ -0,0 +1,77 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.junit.Assert;
import org.junit.Test;
public class TestConnectionCloseOnSqlerr extends BaseTestCase {
static boolean runManuallyNow = true;
@Test
public void test() {
if (runManuallyNow) {
return;
}
try {
for (int i = 0; i < 100; i++) {
try {
Query<Customer> q0 = Ebean.find(Customer.class).where().icontains("namexxx", "Rob")
.query();
q0.findList();
} catch (Exception e) {
if (e.getMessage().contains("Unsuccessfully waited")) {
Assert.fail("No connections found while only one thread is running. (after " + i + " queries)");
} else {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testTransactional() {
if (runManuallyNow) {
return;
}
try {
for (int i = 0; i < 100; i++) {
try {
Ebean.beginTransaction();
Query<Customer> q0 = Ebean.find(Customer.class).where().icontains("namexxx", "Rob")
.query();
q0.findList();
Ebean.commitTransaction();
} catch (Exception e) {
if (e.getMessage().contains("Unsuccessfully waited")) {
Assert.fail("No connections found while only one thread is running. (after " + i + " queries)");
} else {
e.printStackTrace();
}
} finally {
if (Ebean.currentTransaction().isActive()) {
Ebean.rollbackTransaction();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,51 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.BeanState;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.MyLobSize;
import org.junit.Assert;
import org.junit.Test;
import java.util.Set;
public class TestDefaultFetchLazy extends BaseTestCase {
@Test
public void testFetchTypeLazy() {
MyLobSize m = new MyLobSize();
m.setName("aname");
m.setMyCount(10);
m.setMyLob("A big lob of data");
Ebean.save(m);
Assert.assertNotNull(m.getId());
MyLobSize myLobSize = Ebean.find(MyLobSize.class, m.getId());
BeanState beanState = Ebean.getBeanState(myLobSize);
Set<String> loadedProps = beanState.getLoadedProps();
Assert.assertNotNull(loadedProps);
Assert.assertTrue(loadedProps.contains("id"));
Assert.assertTrue(loadedProps.contains("name"));
// FetchType.LAZY properties excluded
Assert.assertFalse(loadedProps.contains("myLob"));
Assert.assertFalse(loadedProps.contains("myCount"));
// the details is also tuned
Query<MyLobSize> queryMany = Ebean.find(MyLobSize.class).fetch("details")// ,"+query")
.where().gt("id", 0).query();
queryMany.findList();
String generatedSql = queryMany.getGeneratedSql();
Assert.assertTrue(generatedSql.contains("t1.other"));
Assert.assertFalse(generatedSql.contains("t1.something"));
}
}
@@ -0,0 +1,124 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class TestExprNestedDisjunction extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
java.sql.Date onAfter = java.sql.Date.valueOf("2009-08-31");
Query<Customer> q = Ebean.find(Customer.class).where()
.disjunction()
.conjunction().startsWith("name", "r").eq("anniversary", onAfter).endJunction()
.conjunction().eq("status", Customer.Status.ACTIVE).gt("id", 0).endJunction()
.orderBy().asc("name");
q.findList();
String s = q.getGeneratedSql();
assertThat(s).contains("(t0.name like ? ");
assertThat(s).contains(" and t0.anniversary = ? ) or (t0.status = ? and t0.id > ? )");
}
@Test
public void test_nested_and() {
ResetBasicData.reset();
java.sql.Date onAfter = java.sql.Date.valueOf("2009-08-31");
Query<Customer> q = Ebean.find(Customer.class)
.where()
.or()
.and()
.startsWith("name", "r").eq("anniversary", onAfter).endAnd()
.and()
.eq("status", Customer.Status.ACTIVE).gt("id", 0).endAnd()
.orderBy().asc("name");
q.findList();
String s = q.getGeneratedSql();
assertThat(s).contains("(t0.name like ? ");
assertThat(s).contains(" and t0.anniversary = ? ) or (t0.status = ? and t0.id > ? )");
}
@Test
public void test_not() {
ResetBasicData.reset();
java.sql.Date onAfter = java.sql.Date.valueOf("2009-08-31");
Query<Customer> q = Ebean.find(Customer.class)
.where()
.not()
.gt("id", 1)
.eq("anniversary", onAfter)
.endNot()
.orderBy().asc("name");
q.findList();
String s = q.getGeneratedSql();
assertThat(s).contains("where not (t0.id > ? and t0.anniversary = ? ) order by t0.name");
}
@Test
public void test_not_nested() {
ResetBasicData.reset();
java.sql.Date onAfter = java.sql.Date.valueOf("2009-08-31");
Query<Customer> q = Ebean.find(Customer.class)
.where()
.or()
.eq("status", Customer.Status.ACTIVE)
.not()
.gt("id", 1)
.eq("anniversary", onAfter)
.orderBy().asc("name");
q.findList();
String s = q.getGeneratedSql();
assertThat(s).contains("where (t0.status = ? or not (t0.id > ? and t0.anniversary = ? ) )");
}
@Test
public void test_not_nested_with_endNot() {
ResetBasicData.reset();
java.sql.Date onAfter = java.sql.Date.valueOf("2009-08-31");
Query<Customer> q = Ebean.find(Customer.class)
.where()
.or()
.eq("status", Customer.Status.ACTIVE)
.not()
.gt("id", 1)
.eq("anniversary", onAfter)
.endNot()
.endOr()
.orderBy().asc("name");
q.findList();
String s = q.getGeneratedSql();
assertThat(s).contains("where (t0.status = ? or not (t0.id > ? and t0.anniversary = ? ) )");
}
}
@@ -0,0 +1,48 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import io.ebean.RawSql;
import io.ebean.RawSqlBuilder;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class TestIContains extends BaseTestCase {
@Test
public void testIContains() {
ResetBasicData.reset();
// case insensitive
Query<Customer> query = Ebean.find(Customer.class).where().icontains("name", "Rob").query();
query.findList();
String generatedSql = query.getGeneratedSql();
assertThat(generatedSql).contains("lower(t0.name)");
// case sensitive
query = Ebean.find(Customer.class).where().contains("name", "Rob").query();
query.findList();
generatedSql = query.getGeneratedSql();
assertThat(generatedSql).contains(" t0.name ");
Ebean.find(Customer.class).where().icontains("name", "Rob").findList();
Ebean.find(Customer.class).where().icontains("name", "Rob").findList();
Ebean.find(Customer.class).where().icontains("name", "Rob").findList();
String sql = "select id, status, name from o_customer where lower(name) like :name";
RawSql parse = RawSqlBuilder.parse(sql).create();
Ebean.find(Customer.class).setRawSql(parse).setParameter("name", "Jim").findList();
}
}
@@ -0,0 +1,69 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
public class TestImplicitJoinOnParentRelationship extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.select("id, name")
.where().eq("orders.details.product.name", "Desk")
.query();
query.findList();
String expectedSql = "select distinct t0.id, t0.name from o_customer t0 join o_order u1 on u1.kcustomer_id = t0.id join o_order_detail u2 on u2.order_id = u1.id join o_product u3 on u3.id = u2.product_id where u3.name = ? ";
Assert.assertEquals(expectedSql, sqlOf(query, 1));
// select distinct t0.id c0, t0.name c1
// from o_customer t0
// join o_order u1 on u1.kcustomer_id = t0.id
// join o_order_detail u2 on u2.order_id = u1.id
// join o_product u3 on u3.id = u2.product_id
// where u3.name = ?
}
@Test
public void testWithDisjunction() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.select("id, name")
.where().disjunction().eq("orders.details.product.name", "Desk").eq("id", 4).endJunction()
.query();
query.findList();
String expectedSql = "select distinct t0.id, t0.name from o_customer t0 left join o_order u1 on u1.kcustomer_id = t0.id left join o_order_detail u2 on u2.order_id = u1.id left join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ? ) ";
Assert.assertEquals(expectedSql, sqlOf(query, 1));
}
@Test
public void testWithOr() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.select("id, name")
.where().or().eq("orders.details.product.name", "Desk").eq("id", 4).endJunction()
.query();
query.findList();
String expectedSql = "select distinct t0.id, t0.name from o_customer t0 left join o_order u1 on u1.kcustomer_id = t0.id left join o_order_detail u2 on u2.order_id = u1.id left join o_product u3 on u3.id = u2.product_id where (u3.name = ? or t0.id = ? ) ";
Assert.assertEquals(expectedSql, sqlOf(query, 1));
}
}
@@ -0,0 +1,35 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Customer;
import org.junit.Test;
import javax.persistence.PersistenceException;
public class TestInvalidFetchPath extends BaseTestCase {
@Test(expected = PersistenceException.class)
public void invalidFetchPathAndProperties_expect_error() {
Ebean.find(Customer.class)
.fetch("notValidPath", "notHaveProps")
.findList();
}
@Test(expected = PersistenceException.class)
public void invalidFetchPath_expect_error() {
Ebean.find(Customer.class)
.fetch("notValidPath")
.findList();
}
@Test
public void fetchWithInvalidPropertyName_expect_allowed() {
Ebean.find(Customer.class)
.fetch("billingAddress", "invalidPropertyName")
.findList();
}
}
@@ -0,0 +1,25 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.EOptOneA;
import org.junit.Assert;
import org.junit.Test;
public class TestJoinOptOneCascade extends BaseTestCase {
@Test
public void test() {
// the left join cascades to the join for c
Query<EOptOneA> query = Ebean.find(EOptOneA.class).fetch("b").fetch("b.c");
query.findList();
String sql = query.getGeneratedSql();
Assert.assertTrue(sql.contains("left join eopt_one_b "));
Assert.assertTrue(sql.contains("left join eopt_one_c "));
}
}
@@ -0,0 +1,35 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
public class TestLimitAlterFetchMany extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
// Due to the use of maxRows... we will convert
// the fetch join to contacts over to a query join
// ... otherwise we wouldn't be able to use the
// limit offset clause
Query<Customer> query = Ebean.find(Customer.class)
// this will automatically get converted to a
// query join ... due to the maxRows
.fetch("contacts").setMaxRows(5);
List<Customer> list = query.findList();
System.out.println(list);
}
}
@@ -0,0 +1,30 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestLimitQuery extends BaseTestCase {
@Test
public void testHasManyWithLimit() {
ResetBasicData.reset();
List<Customer> customers = Ebean.find(Customer.class)
.setAutoTune(false)
.setFirstRow(0)
.setMaxRows(10)
.where().like("name", "%A%")
.findList();
// should at least find the "Cust NoAddress" customer
Assert.assertTrue(!customers.isEmpty());
}
}
@@ -0,0 +1,164 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.Product;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
public class TestManyWhereJoin extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class).select("id,status")
// the where on a 'many' (like orders) requires an
// additional join and distinct which is independent
// of a fetch join (if there is a fetch join)
.where().eq("orders.status", Order.Status.NEW)
// .where().eq("orders.details.product.name", "Desk")
.query();
query.findList();
String sql = sqlOf(query, 1);
// select distinct t0.id c0, t0.status c1
// from o_customer t0
// join o_order u1 on u1.kcustomer_id = t0.id
// where u1.status = ? ; --bind(NEW)
Assert.assertTrue(sql.contains("select distinct "));
Assert.assertTrue(sql.contains("join o_order "));
Assert.assertTrue(sql.contains(".status = ?"));
Assert.assertTrue(sql.contains("select distinct t0.id, t0.status from o_customer t0 join o_order u1 on u1.kcustomer_id = t0.id where u1.status = ?"));
}
@Test
public void testWithFetchJoinAndWhere() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class).select("id,status")
.fetch("orders")
// the where on a 'many' (like orders) requires an
// additional join and distinct which is independent
// of a fetch join (if there is a fetch join)
.where().eq("orders.status", Order.Status.NEW)
// .where().eq("orders.details.product.name", "Desk")
.query();
query.findList();
String sql = sqlOf(query, 3);
// select distinct t0.id c0, t0.status c1,
// t1.id c2, t1.status c3, t1.order_date c4, t1.ship_date c5, t2.name c6, t1.cretime c7, t1.updtime c8, t1.kcustomer_id c9, t0.id
// from o_customer t0
// left join o_order t1 on t1.kcustomer_id = t0.id
// left join o_customer t2 on t2.id = t1.kcustomer_id
// join o_order u1 on u1.kcustomer_id = t0.id
// where t1.order_date is not null and u1.status = ?
// order by t0.id; --bind(NEW)
Assert.assertTrue(sql.contains("select distinct t0.id, t0.status, t1.id, t1.status,"));
Assert.assertTrue(sql.contains("left join o_order t1 on "));
Assert.assertTrue(sql.contains("join o_order u1 on "));
Assert.assertTrue(sql.contains(" u1.status = ?"));
}
@Test
public void testUsingForeignKey() {
ResetBasicData.reset();
Long productId = 1L;
Query<Order> query = Ebean.find(Order.class)
.where().eq("details.product.id", productId)
.orderBy("cretime asc");
query.findList();
String sql = sqlOf(query, 3);
// select distinct t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7, t0.cretime
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// join o_order_detail u1 on u1.order_id = t0.id
// where u1.product_id = ?
// order by t0.cretime; --bind(1)
Assert.assertTrue(sql.contains("select distinct t0.id, t0.status,"));
Assert.assertTrue(sql.contains(" join o_order_detail u1 on u1.order_id = t0.id"));
Assert.assertTrue(sql.contains(" where u1.product_id = ?"));
}
/**
* Same as previous test but use a reference bean.
*/
@Test
public void testUsingForeignKeyReferenceBean() {
ResetBasicData.reset();
Product product = Ebean.getReference(Product.class, 1L);
Query<Order> query = Ebean.find(Order.class)
//.fetch("details")
.where().eq("details.product", product)
.orderBy("cretime asc");
query.findList();
String sql = sqlOf(query, 3);
// select distinct t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7, t0.cretime
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// join o_order_detail u1 on u1.order_id = t0.id
// where u1.product_id = ?
// order by t0.cretime
Assert.assertTrue(sql.contains("select distinct t0.id, t0.status,"));
Assert.assertTrue(sql.contains(" join o_order_detail u1 on u1.order_id = t0.id"));
Assert.assertTrue(sql.contains(" where u1.product_id = ?"));
}
/**
* Additionally add a fetch join.
*/
@Test
public void testUsingForeignKeyAndFetch() {
ResetBasicData.reset();
Product product = Ebean.getReference(Product.class, 1L);
Query<Order> query = Ebean.find(Order.class)
.fetch("details")
.where().eq("details.product", product)
.orderBy("cretime asc");
query.findList();
String sql = sqlOf(query, 3);
// select distinct t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t2.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7,
// t1.id c8, t1.order_qty c9, t1.ship_qty c10, t1.unit_price c11, t1.cretime c12, t1.updtime c13, t1.order_id c14, t1.product_id c15, t0.cretime, t0.id, t1.id, t1.order_qty, t1.cretime
// from o_order t0
// join o_customer t2 on t2.id = t0.kcustomer_id
// left join o_order_detail t1 on t1.order_id = t0.id
// join o_order_detail u1 on u1.order_id = t0.id
// where t1.id > 0 and u1.product_id = ?
// order by t0.cretime, t0.id, t1.id asc, t1.order_qty asc, t1.cretime desc; --bind(1)
Assert.assertTrue(sql.contains("select distinct t0.id, t0.status,"));
Assert.assertTrue(sql.contains(" join o_order_detail u1 on u1.order_id = t0.id"));
Assert.assertTrue(sql.contains(" u1.product_id = ?"));
// additional join for fetching the many details
Assert.assertTrue(sql.contains(" left join o_order_detail t1 on t1.order_id = t0.id"));
}
}
@@ -0,0 +1,95 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.MRole;
import org.tests.model.basic.MUser;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestManyWhereJoinM2M extends BaseTestCase {
@Test
public void test() {
Ebean.beginTransaction();
MRole r1 = new MRole();
r1.setRoleName("role1");
Ebean.save(r1);
MRole r2 = new MRole();
r2.setRoleName("role2special");
Ebean.save(r2);
MRole r3 = new MRole();
r3.setRoleName("role3");
Ebean.save(r3);
MUser u0 = new MUser();
u0.setUserName("user0");
u0.addRole(r1);
u0.addRole(r2);
Ebean.save(u0);
MUser u1 = new MUser();
u1.setUserName("user1");
u1.addRole(r1);
Ebean.save(u1);
MUser u2 = new MUser();
u2.setUserName("user2");
Ebean.save(u2);
Ebean.commitTransaction();
Query<MUser> query = Ebean.find(MUser.class).fetch("roles")
// the where on a 'many' (like orders) requires an
// additional join and distinct which is independent
// of a fetch join (if there is a fetch join)
.where().eq("roles.roleName", "role2special").query();
query.findList();
String sql = query.getGeneratedSql();
Assert.assertTrue(sql.contains("select distinct"));
Assert.assertTrue(sql.contains("left join mrole "));
Assert.assertTrue(sql.contains("join mrole "));
Assert.assertTrue(sql.contains(".role_name = ?"));
isEmpty();
isNotEmpty();
}
private void isEmpty() {
Query<MUser> query = Ebean.find(MUser.class)
.where().isEmpty("roles")
.query();
List<MUser> usersWithNoRoles = query.findList();
assertThat(sqlOf(query, 2)).contains("select t0.userid, t0.user_name, t0.user_type_id from muser t0 where not exists (select 1 from mrole_muser where muser_userid = t0.userid)");
assertThat(usersWithNoRoles).isNotEmpty();
}
private void isNotEmpty() {
Query<MUser> query = Ebean.find(MUser.class)
.select("userName")
.where().isNotEmpty("roles")
.query();
List<MUser> usersWithRoles = query.findList();
assertThat(sqlOf(query, 1)).contains("select t0.userid, t0.user_name from muser t0 where exists (select 1 from mrole_muser where muser_userid = t0.userid)");
assertThat(usersWithRoles).isNotEmpty();
}
}
@@ -0,0 +1,63 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import io.ebean.RawSql;
import io.ebean.RawSqlBuilder;
import org.tests.model.basic.MyAdHoc;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
public class TestMyAdHocSqlSelect extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
String sql = "select order_id, count(*) as detailCount from o_order_detail group by order_id";
RawSql rawSql = RawSqlBuilder
.parse(sql)
.columnMapping("order_id", "order.id")
.create();
Query<MyAdHoc> query = Ebean.find(MyAdHoc.class)
.setRawSql(rawSql)
.where().gt("order_id", 0)
.having().gt("detailCount", 0)
.query();
assertNotNull(query.findList());
assertThat(query.getGeneratedSql()).contains(" group by order_id having count(*) > ?");
}
@Test
public void test_when_explicitColumnMapping() {
ResetBasicData.reset();
String sql = "select order_id, count(*) as detail_count from o_order_detail group by order_id";
RawSql rawSql = RawSqlBuilder
.parse(sql)
.columnMapping("order_id", "order.id")
.columnMapping("detail_count", "detailCount")
.create();
Query<MyAdHoc> query = Ebean.find(MyAdHoc.class)
.setRawSql(rawSql)
.where().gt("order_id", 0)
.having().gt("detailCount", 0)
.query();
assertNotNull(query.findList());
assertThat(query.getGeneratedSql()).contains(" group by order_id having count(*) > ?");
}
}
@@ -0,0 +1,38 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertEquals;
public class TestOneToManyCorrectGrouping extends BaseTestCase {
public static final int EXPECTED_ITERATIONS = 2;
@Test
public void test() {
ResetBasicData.reset();
Query<Customer> customerQuery = Ebean.find(Customer.class)
.fetch("orders")
.where().le("id", 2)
.query();
final AtomicInteger count = new AtomicInteger();
customerQuery.findEach(customer -> {
for (Order order : customer.getOrders()) {
order.getId();
}
count.incrementAndGet();
});
assertEquals(EXPECTED_ITERATIONS, count.get());
}
}
@@ -0,0 +1,65 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.CKeyParent;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
public class TestQueryAlias extends BaseTestCase {
@Test
public void testExists() {
ResetBasicData.reset();
Query<CKeyParent> sq = Ebean.createQuery(CKeyParent.class)
.select("id.oneKey").alias("st0")
.setAutoTune(false).where().query();
Query<CKeyParent> pq = Ebean.find(CKeyParent.class).alias("myt0").where().in("id.oneKey", sq).query();
pq.findList();
String sql = pq.getGeneratedSql();
// Without alias command is should be:
// select t0.one_key c0, t0.two_key c1, t0.name c2, t0.version c3, t0.assoc_id c4 from ckey_parent t0 where (t0
// .one_key) in (select t0.one_key from ckey_parent t0)
// but with alias command SQL should look like this:
// select myt0.one_key c0, myt0.two_key c1, myt0.name c2, myt0.version c3, myt0.assoc_id c4 from ckey_parent myt0
// where (myt0.one_key) in (select st0.one_key from ckey_parent st0)
Assert.assertTrue(sql.contains("ckey_parent myt0"));
Assert.assertTrue(sql.contains("(myt0.one_key) in (select st0.one_key from ckey_parent st0)"));
}
@Test
public void testNotExists() {
ResetBasicData.reset();
Query<CKeyParent> sq = Ebean.createQuery(CKeyParent.class)
.select("id.oneKey").alias("st0")
.setAutoTune(false).where().query();
Query<CKeyParent> pq = Ebean.find(CKeyParent.class).alias("myt0").where().notIn("id.oneKey", sq).query();
pq.findList();
String sql = pq.getGeneratedSql();
// Without alias command is should be:
// select t0.one_key c0, t0.two_key c1, t0.name c2, t0.version c3, t0.assoc_id c4 from ckey_parent t0 where (t0
// .one_key) in (select t0.one_key from ckey_parent t0)
// but with alias command SQL should look like this:
// select myt0.one_key c0, myt0.two_key c1, myt0.name c2, myt0.version c3, myt0.assoc_id c4 from ckey_parent myt0
// where (myt0.one_key) in (select st0.one_key from ckey_parent st0)
Assert.assertTrue(sql.contains("ckey_parent myt0"));
Assert.assertTrue(sql.contains("(myt0.one_key) not in (select st0.one_key from ckey_parent st0)"));
}
}
@@ -0,0 +1,91 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestQueryExists extends BaseTestCase {
@Test
public void testExists_orders_onOneToMany() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.where().raw("exists (select 1 from o_order_detail where order_id = t0.id)")
.query();
List<Order> ordersThatHave = query.findList();
Query<Order> query2 = Ebean.find(Order.class)
.where().raw("not exists (select 1 from o_order_detail where order_id = t0.id)")
.query();
List<Order> ordersThatDontHave = query2.findList();
assertThat(query.getGeneratedSql()).contains(" exists (");
assertThat(query2.getGeneratedSql()).contains(" not exists (");
assertThat(ordersThatHave).isNotEmpty();
assertThat(ordersThatDontHave).isNotEmpty();
}
@Test
public void testExists_onOneToMany() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.where().raw("exists (select 1 from contact where customer_id = t0.id)")
.query();
List<Customer> customersWithContacts = query.findList();
Query<Customer> query2 = Ebean.find(Customer.class)
.where().raw("not exists (select 1 FROM contact where customer_id = t0.id)")
.query();
query2.findList();
assertThat(query.getGeneratedSql()).contains(" exists (");
assertThat(query2.getGeneratedSql()).contains(" not exists (");
assertThat(customersWithContacts).isNotEmpty();
}
@Test
public void testExists() {
ResetBasicData.reset();
Query<Order> subQuery = Ebean.find(Order.class).alias("sq").select("id").where().raw("sq.kcustomer_id = qt.id").query();
Query<Customer> query = Ebean.find(Customer.class).alias("qt").where().exists(subQuery).query();
query.findList();
String sql = query.getGeneratedSql();
Assert.assertTrue(sql.indexOf("exists (") > 0);
}
@Test
public void testNotExists() {
ResetBasicData.reset();
Query<Order> subQuery = Ebean.find(Order.class).alias("sq").select("id").where().raw("sq.kcustomer_id = qt.id").query();
Query<Customer> query = Ebean.find(Customer.class).alias("qt").where().notExists(subQuery).query();
query.findList();
String sql = query.getGeneratedSql();
Assert.assertTrue(sql.indexOf("not exists (") > 0);
}
}
@@ -0,0 +1,46 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryFetchJoinWithOrder extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Order> list = Ebean.find(Order.class)
.fetch("details", new FetchConfig().query())
.order().asc("id")
.order().desc("details.id").findList();
Assert.assertNotNull(list);
List<Order> list2 = Ebean.find(Order.class)
.fetch("customer", new FetchConfig().query(5))
.fetch("customer.contacts")
.order().asc("id")
.order().asc("customer.contacts.lastName")
.findList();
Assert.assertNotNull(list2);
List<Customer> list3 = Ebean.find(Customer.class)
.fetch("orders")
.filterMany("orders").eq("status", Order.Status.NEW)
.order().desc("orders.id")
.findList();
Assert.assertNotNull(list3);
}
}
@@ -0,0 +1,161 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import io.ebeaninternal.api.SpiQuery;
import org.tests.model.basic.Contact;
import org.tests.model.basic.Customer;
import org.tests.model.basic.OrderShipment;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryFetchManyTwoDeep extends BaseTestCase {
@Test
public void testFetchOneToManyWithChildOneToMany() {
ResetBasicData.reset();
// test that join to order.details is not included in the initial query (included in query join)
Query<Customer> query = Ebean.find(Customer.class)
.setAutoTune(false)
.fetch("orders")
.fetch("orders.details");
SpiQuery<?> spiQuery = (SpiQuery<?>) query;
spiQuery.setLogSecondaryQuery(true);
List<Customer> list = query.findList();
Assert.assertTrue("has rows", !list.isEmpty());
Assert.assertTrue(query.getGeneratedSql().contains("from o_customer t0 "));
Assert.assertTrue(query.getGeneratedSql().contains("left join o_order t1 on t1.kcustomer_id = t0.id"));
Assert.assertTrue(query.getGeneratedSql().contains("left join o_customer t2 on t2.id = t1.kcustomer_id"));
Assert.assertFalse(query.getGeneratedSql().contains("join or_order_ship"));
//select t0.id c0, t0.status c1, t0.name c2, t0.smallnote c3, t0.anniversary c4, t0.cretime c5, t0.updtime c6, t0.billing_address_id c7, t0.shipping_address_id c8, t1.id c9, t1.status c10, t1.order_date c11, t1.ship_date c12,
// t2.name c13, t1.cretime c14, t1.updtime c15, t1.kcustomer_id c16
// from o_customer t0
// left join o_order t1 on t1.kcustomer_id = t0.id
// left join o_customer t2 on t2.id = t1.kcustomer_id
// where t1.order_date is not null order by t0.id; --bind()
List<SpiQuery<?>> secondaryQueries = spiQuery.getLoggedSecondaryQueries();
Assert.assertNotNull(secondaryQueries);
Assert.assertEquals(1, secondaryQueries.size());
SpiQuery<?> secondaryQuery = secondaryQueries.get(0);
String secondarySql = secondaryQuery.getGeneratedSql();
Assert.assertTrue(secondarySql.contains("from o_order_detail t0 where t0.id > 0 and (t0.order_id) in"));
// select t0.order_id c0, t0.id c1, t0.order_qty c2, t0.ship_qty c3, t0.unit_price c4, t0.cretime c5, t0.updtime c6, t0.order_id c7, t0.product_id c8
// from o_order_detail t0
// where (t0.order_id) in (?,?,?,?,?)
}
@Test
public void testFetchOptionalManyToOneThenDownToMany() {
ResetBasicData.reset();
// test that join to order.details is not included
Query<OrderShipment> shipQuery = Ebean.find(OrderShipment.class)
.setAutoTune(false)
.fetch("order")
.fetch("order.details");
List<OrderShipment> shipList = shipQuery.findList();
Assert.assertTrue("has rows", !shipList.isEmpty());
String generatedSql = shipQuery.getGeneratedSql();
// select ...
// from or_order_ship t0
// left join o_order t1 on t1.id = t0.order_id
// left join o_customer t3 on t3.id = t1.kcustomer_id
// left join o_order_detail t2 on t2.order_id = t1.id
// where t2.id > 0 ; --bind()
Assert.assertTrue(generatedSql.contains("from or_order_ship t0"));
// Relationship from OrderShipment to Order is optional so outer join here
Assert.assertTrue(generatedSql.contains("left join o_order t1 on t1.id = t0.order_id"));
Assert.assertTrue(generatedSql.contains("left join o_customer t3 on t3.id = t1.kcustomer_id"));
Assert.assertTrue(generatedSql.contains("left join o_order_detail t2 on t2.order_id = t1.id"));
// If OrderShipment to Order is not optional you get inner joins up to o_order_detail (which is a many)
// select ...
// from or_order_ship t0
// join o_order t1 on t1.id = t0.order_id
// join o_customer t3 on t3.id = t1.kcustomer_id
// left join o_order_detail t2 on t2.order_id = t1.id
// where t2.id > 0 ; --bind()
}
@Test
public void testFetchMandatoryManyToOneThenDownToMany() {
ResetBasicData.reset();
// test that join to order.details is not included
Query<Contact> query = Ebean.find(Contact.class)
.setAutoTune(false)
.fetch("customer")
.fetch("customer.orders");
List<Contact> shipList = query.findList();
Assert.assertTrue("has rows", !shipList.isEmpty());
String generatedSql = query.getGeneratedSql();
// select ...
// from contact t0
// join o_customer t1 on t1.id = t0.customer_id
// left join o_order t2 on t2.kcustomer_id = t1.id
// left join o_customer t3 on t3.id = t2.kcustomer_id
// where t2.order_date is not null ; --bind()
Assert.assertTrue(generatedSql.contains("from contact t0 "));
// Relationship from Contact to Customer is mandatory so inner join here
Assert.assertTrue(generatedSql.contains("join o_customer t1 on t1.id = t0.customer_id"));
// outer join on many relationship 'orders'
Assert.assertTrue(generatedSql.contains("left join o_order t2 on t2.kcustomer_id = t1.id"));
}
@Test
public void testFetchMandatoryManyToOneWithPredicate() {
ResetBasicData.reset();
// test that join to order.details is not included
Query<Contact> query = Ebean.find(Contact.class)
.setAutoTune(false)
.fetch("customer")
.where().ilike("customer.name", "Rob%")
.query();
List<Contact> list = query.findList();
Assert.assertTrue("has rows", !list.isEmpty());
String generatedSql = query.getGeneratedSql();
// select ...
// from contact t0
// join o_customer t1 on t1.id = t0.customer_id
// where lower(t1.name) like ? ; --bind(rob%)
Assert.assertTrue(generatedSql.contains("from contact t0 "));
Assert.assertTrue(generatedSql.contains("join o_customer t1 on t1.id = t0.customer_id"));
Assert.assertTrue(generatedSql.contains("where lower(t1.name) like ?"));
}
}
@@ -0,0 +1,43 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Contact;
import org.tests.model.basic.ContactNote;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
public class TestQueryFetchSkipPath extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Order> list = Ebean.find(Order.class)
// .setAutoTune(true)
.setAutoTune(false).select("status")
// .fetch("customer","id")
// .fetch("customer.contacts","id")
.fetch("customer.contacts.notes", "title").findList();
for (Order order : list) {
order.getStatus();
Customer customer = order.getCustomer();
List<Contact> contacts = customer.getContacts();
for (Contact contact : contacts) {
List<ContactNote> notes = contact.getNotes();
for (ContactNote contactNote : notes) {
contactNote.getTitle();
}
}
}
}
}
@@ -0,0 +1,64 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class TestQueryFilterMany extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Customer customer = Ebean.find(Customer.class)
.fetch("orders", new FetchConfig().lazy())
.filterMany("orders").eq("status", Order.Status.NEW)
.where().ieq("name", "Rob")
.order().asc("id").setMaxRows(1)
.findList().get(0);
customer.getOrders().size();
List<String> sqlList = LoggedSqlCollector.stop();
assertEquals(2, sqlList.size());
assertTrue(sqlList.get(1).contains("status = ?"));
// Currently this does not include the query filter
Ebean.refreshMany(customer, "orders");
}
@Test
public void testNestedFilterMany() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Customer.class)
.filterMany("contacts").isNotNull("firstName")
.filterMany("contacts.notes").istartsWith("title", "foo")
.findList();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(3);
assertThat(sql.get(0)).contains(" from o_customer t0; --bind()");
assertThat(sql.get(1)).contains(" from contact t0 where (t0.customer_id) in");
assertThat(sql.get(1)).contains(" and t0.first_name is not null");
assertThat(sql.get(2)).contains(" from contact_note t0 where (t0.contact_id) in");
assertThat(sql.get(2)).contains(" and lower(t0.title) like");
}
}
@@ -0,0 +1,17 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.MUser;
import org.junit.Test;
public class TestQueryFilterManyOnM2M extends BaseTestCase {
@Test
public void test() {
Ebean.find(MUser.class).fetch("roles").filterMany("roles").ilike("roleName", "Jim%").findList();
}
}
@@ -0,0 +1,62 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.OrderDetail;
import org.tests.model.basic.Product;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryFilterManyOnSecondary extends BaseTestCase {
@Test
public void testFilterManyWithSimplePredicate() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.fetch("orders", new FetchConfig().query())
.where().ilike("name", "Rob%").gt("id", 0)
.filterMany("orders").eq("status", Order.Status.NEW)
.query();
List<Customer> list = query.findList();
for (Customer customer : list) {
List<Order> orders = customer.getOrders();
for (Order order : orders) {
Assert.assertEquals(Order.Status.NEW, order.getStatus());
}
}
}
@Test
public void testFilterManyWithPathPredicate() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.fetch("details", new FetchConfig().query())
.fetch("details.product", "name")
.filterMany("details").ilike("product.name", "c%")
.query();
List<Order> orders = query.findList();
for (Order order : orders) {
List<OrderDetail> details = order.getDetails();
for (OrderDetail orderDetail : details) {
Product product = orderDetail.getProduct();
String name = product.getName();
Assert.assertTrue(name.startsWith("C"));
}
}
}
}
@@ -0,0 +1,35 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.sql.Date;
import java.util.List;
public class TestQueryFilterManySimple extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
// not really last week :)
Date lastWeek = Date.valueOf("2010-01-01");
List<Customer> list = Ebean
.find(Customer.class)
// .join("orders", new JoinConfig().lazy())
// .join("orders", new JoinConfig().query())
.fetch("orders").fetch("contacts", new FetchConfig().query()).where().ilike("name", "rob%")
.filterMany("orders").eq("status", Order.Status.NEW).gt("orderDate", lastWeek)
.filterMany("contacts").isNotNull("firstName").findList();
// invoke lazy loading
list.get(0).getOrders().size();
}
}
@@ -0,0 +1,65 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.FetchConfig;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
public class TestQueryFindEach extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
Query<Customer> query
= server.find(Customer.class)
.setAutoTune(false)
.fetch("contacts", new FetchConfig().query(2)).where().gt("id", 0).orderBy("id")
.setMaxRows(2);
final AtomicInteger counter = new AtomicInteger(0);
query.findEach(customer -> {
counter.incrementAndGet();
customer.getName();
});
Assert.assertEquals(2, counter.get());
}
/**
* Test the behaviour when an exception is thrown inside the findVisit().
*/
@Test(expected = IllegalStateException.class)
public void testVisitThrowingException() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
Query<Customer> query = server.find(Customer.class).setAutoTune(false)
.fetch("contacts", new FetchConfig().query(2)).where().gt("id", 0).orderBy("id")
.setMaxRows(2);
final AtomicInteger counter = new AtomicInteger(0);
query.findEach(customer -> {
counter.incrementAndGet();
if (counter.intValue() > 0) {
throw new IllegalStateException("cause a failure");
}
});
Assert.assertFalse("Never get here - exception thrown", true);
}
}
@@ -0,0 +1,67 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.FetchConfig;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
public class TestQueryFindEachWhile extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
Query<Customer> query
= server.find(Customer.class)
.setAutoTune(false)
.fetch("contacts", new FetchConfig().query(2)).where().gt("id", 0).orderBy("id")
.setMaxRows(2);
final AtomicInteger counter = new AtomicInteger(0);
query.findEachWhile(customer -> {
counter.incrementAndGet();
customer.getName();
return true;
});
Assert.assertEquals(2, counter.get());
}
/**
* Test the behaviour when an exception is thrown inside the findVisit().
*/
@Test(expected = IllegalStateException.class)
public void testVisitThrowingException() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
Query<Customer> query = server.find(Customer.class).setAutoTune(false)
.fetch("contacts", new FetchConfig().query(2)).where().gt("id", 0).orderBy("id")
.setMaxRows(2);
final AtomicInteger counter = new AtomicInteger(0);
query.findEachWhile(customer -> {
counter.incrementAndGet();
if (counter.intValue() > 0) {
throw new IllegalStateException("cause a failure");
}
return true;
});
Assert.assertFalse("Never get here - exception thrown", true);
}
}
@@ -0,0 +1,68 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FutureList;
import io.ebean.Transaction;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static org.junit.Assert.assertEquals;
public class TestQueryFindFutureList extends BaseTestCase {
@Test
public void test_cancel() throws InterruptedException {
ResetBasicData.reset();
// warm the connection pool
Transaction t0 = Ebean.getServer(null).createTransaction();
Transaction t1 = Ebean.getServer(null).createTransaction();
Transaction t2 = Ebean.getServer(null).createTransaction();
t0.end();
t1.end();
t2.end();
FutureList<Order> futureList = Ebean.find(Order.class).findFutureList();
Thread.sleep(10);
futureList.cancel(true);
// don't shutdown immediately
Thread.sleep(50);
}
@Test
public void test_findFutureList() throws InterruptedException {
ResetBasicData.reset();
FutureList<Order> futureList = Ebean.find(Order.class).findFutureList();
// wait for it to complete
List<Order> orders = futureList.getUnchecked();
assertEquals(Ebean.find(Order.class).findCount(), orders.size());
}
@Test
public void test_findFutureListWithTimeout() throws InterruptedException, TimeoutException {
ResetBasicData.reset();
FutureList<Order> futureList = Ebean.find(Order.class).findFutureList();
// wait for it to complete
List<Order> orders = futureList.getUnchecked(1, TimeUnit.SECONDS);
assertEquals(Ebean.find(Order.class).findCount(), orders.size());
}
}
@@ -0,0 +1,227 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.Query;
import io.ebean.QueryIterator;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.OrderShipment;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import javax.persistence.PersistenceException;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class TestQueryFindIterate extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
Query<Customer> query = server.find(Customer.class)
.setMaxRows(2);
final AtomicInteger count = new AtomicInteger();
try (QueryIterator<Customer> it = query.findIterate()) {
while (it.hasNext()) {
Customer customer = it.next();
customer.getName();
count.incrementAndGet();
}
}
assertEquals(2, count.get());
}
@Test
public void test_hasNext_hasNext() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
QueryIterator<Customer> queryIterator = server.find(Customer.class)
.where()
.isNotNull("name")
.setMaxRows(3)
.order().asc("id")
.findIterate();
try {
// check that hasNext does not move to the next bean
assertTrue(queryIterator.hasNext());
assertTrue(queryIterator.hasNext());
assertTrue(queryIterator.hasNext());
assertTrue(queryIterator.hasNext());
assertTrue(queryIterator.hasNext());
Customer first = queryIterator.next();
logger.info("first: {}", queryIterator.next());
assertEquals(first.getId(), Integer.valueOf(1));
while (queryIterator.hasNext()) {
logger.info("next: {}", queryIterator.next());
}
} finally {
queryIterator.close();
}
}
@Test
public void findEach() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
Query<Customer> query = server.find(Customer.class)
.setAutoTune(false)
//.fetch("contacts", new FetchConfig().query(2)).where().gt("id", 0).orderBy("id")
.setMaxRows(2);
final AtomicInteger count = new AtomicInteger();
query.findEach(bean -> count.incrementAndGet());
assertEquals(2, count.get());
}
@Test
public void testWithLazyLoading() {
ResetBasicData.reset();
Ebean.find(Order.class)
//.select("orderDate")
.where().gt("id", 0).le("id", 10)
.findEach(order -> {
Customer customer = order.getCustomer();
// invoke lazy loading on customer, order details and order shipments
order.getId();
customer.getName();
order.getDetails().size();
order.getShipments().size();
});
}
@Test
public void testWithLazyBatchSize() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Order.class)
.setLazyLoadBatchSize(10)
.select("status, orderDate")
.fetch("customer", "name")
.where().gt("id", 0).le("id", 10)
.setUseCache(false)
.findEach(order -> {
Customer customer = order.getCustomer();
customer.getName();
order.getDetails().size();
order.getShipments().size();
});
List<String> loggedSql = LoggedSqlCollector.stop();
assertEquals(3, loggedSql.size());
assertTrue(trimSql(loggedSql.get(0), 7).contains("select t0.id, t0.status, t0.order_date, t1.id, t1.name from o_order t0 join o_customer t1"));
assertTrue(trimSql(loggedSql.get(1), 7).contains("select t0.order_id, t0.id, t0.order_qty, t0.ship_qty, t0.unit_price"));
assertTrue(trimSql(loggedSql.get(2), 7).contains("select t0.order_id, t0.id, t0.ship_time, t0.cretime, t0.updtime, t0.version, t0.order_id from or_order_ship"));
}
@Test
public void testWithTwoJoins() {
ResetBasicData.reset();
LoggedSqlCollector.start();
// make sure we don't hit the L2 cache for order shipments
Ebean.getServerCacheManager().clear(Order.class);
Ebean.getServerCacheManager().clear(OrderShipment.class);
Ebean.find(Order.class)
.setLazyLoadBatchSize(10)
.setUseCache(false)
.select("status, orderDate")
.fetch("customer", "name")
.fetch("details")
.where().gt("id", 0).le("id", 10)
.order().asc("id")
.findEach(order -> {
Customer customer = order.getCustomer();
order.getId();
customer.getName();
order.getDetails().size();
order.getShipments().size();
});
List<String> loggedSql = LoggedSqlCollector.stop();
assertEquals("Got SQL: " + loggedSql, 2, loggedSql.size());
assertThat(trimSql(loggedSql.get(0), 7).contains("select t0.id, t0.status, t0.order_date, t1.id, t1.name, t2.id, t2.order_qty, t2.ship_qty"));
assertThat(trimSql(loggedSql.get(1), 7).contains("select t0.order_id, t0.id, t0.ship_time, t0.cretime, t0.updtime, t0.version, t0.order_id from or_order_ship"));
}
@Test(expected = PersistenceException.class)
public void testWithExceptionInQuery() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
// intentionally a query with incorrect type binding
Query<Customer> query = server.find(Customer.class)
.setAutoTune(false)
.where().gt("id", "JUNK_NOT_A_LONG")
.setMaxRows(2);
// this throws an exception immediately
query.findEach(bean -> {
});
if (!server.getName().equals("h2")) {
// MySql allows the query with type conversion?
throw new PersistenceException("H2 does expected thing but MySql does not");
}
assertTrue("Never get here as exception thrown", false);
}
@Test(expected = IllegalStateException.class)
public void testWithExceptionInLoop() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
Query<Customer> query = server.find(Customer.class)
.setAutoTune(false)
.where().gt("id", 0)
.setMaxRows(2);
query.findEach(customer -> {
if (customer != null) {
throw new IllegalStateException("cause an exception");
}
});
}
}
@@ -0,0 +1,39 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Product;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
public class TestQueryFindMapTypedKey extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Map<String, Product> productsBySku = Ebean.find(Product.class)
.setMapKey("sku")
.findMap();
assertThat(productsBySku).isNotEmpty();
Product desk = productsBySku.get("DSK1");
assertNotNull(desk);
Map<String, Customer> map = Ebean.find(Customer.class)
.select("id, name")
.setMapKey("name")
.findMap();
assertNotNull(map);
}
}
@@ -0,0 +1,252 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.PagedList;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import javax.persistence.PersistenceException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.*;
public class TestQueryFindPagedList extends BaseTestCase {
@Test(expected = PersistenceException.class)
public void test_noMaxRows() throws ExecutionException, InterruptedException {
Ebean.find(Order.class).findPagedList();
}
@Test
public void test_maxRows_NoCount() throws ExecutionException, InterruptedException {
ResetBasicData.reset();
PagedList<Order> pagedList = Ebean.find(Order.class)
.setMaxRows(4)
.findPagedList();
LoggedSqlCollector.start();
List<Order> orders = pagedList.getList();
assertTrue(!orders.isEmpty());
List<String> loggedSql = LoggedSqlCollector.stop();
assertEquals("Only 1 SQL statement, no count query", 1, loggedSql.size());
}
@Test
public void test_maxRows_countInBackground() throws ExecutionException, InterruptedException, TimeoutException {
ResetBasicData.reset();
PagedList<Order> pagedList = Ebean.find(Order.class)
.setMaxRows(3)
.findPagedList();
Future<Integer> rowCount = pagedList.getFutureCount();
List<Order> orders = pagedList.getList();
// these are each getting the total row count
int totalRowCount = pagedList.getTotalCount();
Integer totalRowCountWithTimeout = rowCount.get(30, TimeUnit.SECONDS);
Integer totalRowCountViaFuture = rowCount.get();
assertTrue(orders.size() < totalRowCount);
assertEquals(Integer.valueOf(totalRowCount), totalRowCountViaFuture);
assertEquals(Integer.valueOf(totalRowCount), totalRowCountWithTimeout);
}
@Test
public void test_maxRows_countInBackground_withLoadRowCount() throws InterruptedException {
ResetBasicData.reset();
// fetch less that total orders (page size 3)
PagedList<Order> pagedList = Ebean.find(Order.class)
.setMaxRows(3)
.findPagedList();
pagedList.loadCount();
List<Order> orders = pagedList.getList();
int totalRowCount = pagedList.getTotalCount();
assertThat(orders.size()).isLessThan(totalRowCount);
assertTrue(pagedList.hasNext());
assertFalse(pagedList.hasPrev());
// fetch less that total orders (page size 3)
PagedList<Order> pagedList2 = Ebean.find(Order.class)
.setFirstRow(1)
.setMaxRows(3)
.findPagedList();
pagedList2.loadCount();
List<Order> orders2 = pagedList2.getList();
int totalRowCount2 = pagedList2.getTotalCount();
assertTrue(pagedList2.hasNext());
assertTrue(pagedList2.hasPrev());
assertThat(totalRowCount).isEqualTo(totalRowCount2);
assertThat(orders2.size()).isLessThan(totalRowCount);
PagedList<Order> pagedList3 = Ebean.find(Order.class)
.setFirstRow(2)
.setMaxRows(150)
.findPagedList();
assertFalse(pagedList3.hasNext());
assertTrue(pagedList3.hasPrev());
List<Order> list3 = pagedList3.getList();
String xtoYofZ = pagedList3.getDisplayXtoYofZ(" to ", " of ");
assertThat(xtoYofZ).isEqualTo("3 to " + totalRowCount + " of " + totalRowCount);
assertThat(list3.size()).isEqualTo(totalRowCount - 2);
PagedList<Order> pagedList4 = Ebean.find(Order.class)
.setFirstRow(0)
.setMaxRows(totalRowCount)
.findPagedList();
assertFalse(pagedList4.hasNext());
assertFalse(pagedList4.hasPrev());
assertThat(pagedList4.getDisplayXtoYofZ(" to ", " of ")).isEqualTo("1 to " + totalRowCount + " of " + totalRowCount);
PagedList<Order> pagedList5 = Ebean.find(Order.class)
.setFirstRow(0)
.setMaxRows(totalRowCount - 1)
.findPagedList();
assertTrue(pagedList5.hasNext());
assertFalse(pagedList5.hasPrev());
}
@Test
public void test_noCount() throws ExecutionException, InterruptedException {
ResetBasicData.reset();
PagedList<Order> pagedList = Ebean.find(Order.class).setMaxRows(4).findPagedList();
LoggedSqlCollector.start();
List<Order> orders = pagedList.getList();
assertTrue(!orders.isEmpty());
List<String> loggedSql = LoggedSqlCollector.stop();
assertEquals("Only 1 SQL statement, no count query", 1, loggedSql.size());
}
@Test
public void test_countInBackground() throws ExecutionException, InterruptedException, TimeoutException {
ResetBasicData.reset();
PagedList<Order> pagedList = Ebean.find(Order.class).setMaxRows(3).findPagedList();
Future<Integer> rowCount = pagedList.getFutureCount();
List<Order> orders = pagedList.getList();
// these are each getting the total row count
int totalRowCount = pagedList.getTotalCount();
Integer totalRowCountWithTimeout = rowCount.get(30, TimeUnit.SECONDS);
Integer totalRowCountViaFuture = rowCount.get();
assertTrue(orders.size() < totalRowCount);
assertEquals(Integer.valueOf(totalRowCount), totalRowCountViaFuture);
assertEquals(Integer.valueOf(totalRowCount), totalRowCountWithTimeout);
}
@Test
public void test_countInBackground_withLoadRowCount() throws InterruptedException {
ResetBasicData.reset();
// fetch less that total orders (page size 3)
PagedList<Order> pagedList = Ebean.find(Order.class).setMaxRows(3).findPagedList();
pagedList.loadCount();
List<Order> orders = pagedList.getList();
int totalRowCount = pagedList.getTotalCount();
assertThat(orders.size()).isLessThan(totalRowCount);
}
@Test
public void test_countUsingForegound() throws ExecutionException, InterruptedException {
ResetBasicData.reset();
PagedList<Order> pagedList = Ebean.find(Order.class).setMaxRows(6).findPagedList();
LoggedSqlCollector.start();
// kinda not normal but just wrap in a transaction to assert
// the background fetch does not occur (which explicitly creates
// its own transaction) ... so a bit naughty with the test here
Ebean.beginTransaction();
try {
List<Order> orders = pagedList.getList();
int totalRowCount = pagedList.getTotalCount();
// invoke it again but cached...
int totalRowCountAgain = pagedList.getTotalCount();
List<String> loggedSql = LoggedSqlCollector.stop();
assertTrue(orders.size() < totalRowCount);
assertEquals(2, loggedSql.size());
assertEquals(totalRowCount, totalRowCountAgain);
String firstTxn = loggedSql.get(0).substring(0, 10);
String secTxn = loggedSql.get(1).substring(0, 10);
assertEquals(firstTxn, secTxn);
} finally {
Ebean.endTransaction();
}
}
@Test
public void test_usingAlias() throws ExecutionException, InterruptedException {
ResetBasicData.reset();
PagedList<Order> pagedList = Ebean.find(Order.class)
.alias("b")
.where().raw("b.id > 0")
.setMaxRows(6)
.findPagedList();
LoggedSqlCollector.start();
pagedList.getTotalCount();
pagedList.getList();
List<String> loggedSql = LoggedSqlCollector.stop();
assertEquals(2, loggedSql.size());
assertThat(loggedSql.get(0)).contains("select count(*) from o_order b where b.id > 0");
assertThat(trimSql(loggedSql.get(1), 3)).contains(" b.id, b.status, b.order_date");
}
}
@@ -0,0 +1,47 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Article;
import org.tests.model.basic.Section;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryFindReadOnly extends BaseTestCase {
@Test
public void test() {
Section s0 = new Section("some content");
Article a0 = new Article("art1", "auth1");
a0.addSection(s0);
Ebean.save(a0);
Article ar1 = Ebean.find(Article.class).setReadOnly(true).setId(a0.getId()).findUnique();
Assert.assertNotNull(ar1);
Assert.assertTrue("readonly", Ebean.getBeanState(ar1).isReadOnly());
List<Section> ar1sections = ar1.getSections();
Assert.assertEquals(1, ar1sections.size());
Section s2 = ar1sections.get(0);
Assert.assertTrue("readonly cascading", Ebean.getBeanState(s2).isReadOnly());
Ebean.find(Article.class).setLoadBeanCache(true).findList();
Article ar0 = Ebean.find(Article.class, a0.getId());
Assert.assertNotNull(ar0);
Assert.assertFalse(Ebean.getBeanState(ar0).isReadOnly());
List<Section> ar0sections = ar0.getSections();
Section s1 = ar0sections.get(0);
Assert.assertFalse(Ebean.getBeanState(s1).isReadOnly());
}
}
@@ -0,0 +1,60 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.FetchConfig;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
public class TestQueryFindVisit extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
Query<Customer> query = server.find(Customer.class).setAutoTune(false)
.fetch("contacts", new FetchConfig().query(2)).where().gt("id", 0).orderBy("id")
.setMaxRows(2);
final AtomicInteger counter = new AtomicInteger(0);
query.findEach(bean -> counter.incrementAndGet());
Assert.assertEquals(2, counter.get());
}
/**
* Test the behaviour when an exception is thrown inside the findVisit().
*/
@Test(expected = IllegalStateException.class)
public void testVisitThrowingException() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
Query<Customer> query = server.find(Customer.class).setAutoTune(false)
.fetch("contacts", new FetchConfig().query(2)).where().gt("id", 0).orderBy("id")
.setMaxRows(2);
final AtomicInteger counter = new AtomicInteger(0);
query.findEach(bean -> {
counter.incrementAndGet();
if (counter.intValue() > 0) {
throw new IllegalStateException("cause a failure");
}
});
Assert.assertFalse("Never get here - exception thrown", true);
}
}
@@ -0,0 +1,32 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryInAssocOne extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Customer> list = Ebean.find(Customer.class).where().lt("id", 200).findList();
Query<Order> query = Ebean.find(Order.class).where().in("customer", list).query();
query.findList();
String sql = query.getGeneratedSql();
Assert.assertTrue(sql, sql.contains("join o_customer t1 on t1.id = t0.kcustomer_id"));
Assert.assertTrue(sql, sql.contains("t0.kcustomer_id in (?"));
}
}
@@ -0,0 +1,24 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.assertNotNull;
public class TestQueryInIdTypeConversion extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Customer> list = Ebean.find(Customer.class).where().idIn("1", "2").findList();
assertNotNull(list);
}
}
@@ -0,0 +1,106 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.tests.model.m2m.Role;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class TestQueryIsNull extends BaseTestCase {
@Test
public void queryShouldContainIsNullOnColumn() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class).where().isNull("customerName").query();
query.findList();
assertTrue(query.getGeneratedSql().contains("name is null"));
}
@Test
public void isNotNull_when_OneToMany_expect_existsSubquery() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class).where().isNotNull("details").query();
query.findList();
assertTrue(query.getGeneratedSql().contains(" where exists (select 1 from o_order_detail where order_id = t0.id)"));
}
@Test
public void isNotEmpty_when_OneToMany_expect_existsSubquery() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class).where().isNotEmpty("details").query();
query.findList();
assertTrue(query.getGeneratedSql().contains(" where exists (select 1 from o_order_detail where order_id = t0.id)"));
}
@Test
public void isNull_when_OneToMany_expect_notExistsSubquery() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class).where().isNull("details").query();
query.findList();
assertTrue(query.getGeneratedSql().contains(" where not exists (select 1 from o_order_detail where order_id = t0.id)"));
}
@Test
public void isEmpty_when_OneToMany_expect_notExistsSubquery() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class).where().isEmpty("details").query();
query.findList();
assertTrue(query.getGeneratedSql().contains(" where not exists (select 1 from o_order_detail where order_id = t0.id)"));
}
@Test
public void isEmpty_when_ManyToMany_expect_notExistsSubqueryAndNoJoin() {
ResetBasicData.reset();
Query<Role> query = Ebean.find(Role.class).where().isEmpty("permissions").query();
query.findList();
assertTrue(query.getGeneratedSql().contains("from mt_role t0 where not exists (select 1 from mt_role_permission where mt_role_id = t0.id)"));
}
@Test
public void isNull_when_ManyToMany_expect_notExistsSubqueryAndNoJoin() {
ResetBasicData.reset();
Query<Role> query = Ebean.find(Role.class).where().isNull("permissions").query();
query.findList();
assertTrue(query.getGeneratedSql().contains("from mt_role t0 where not exists (select 1 from mt_role_permission where mt_role_id = t0.id)"));
}
@Test
public void isNotEmpty_when_ManyToMany_expect_existsSubqueryAndNoJoin() {
ResetBasicData.reset();
Query<Role> query = Ebean.find(Role.class).where().isNotEmpty("permissions").query();
query.findList();
assertTrue(query.getGeneratedSql().contains("from mt_role t0 where exists (select 1 from mt_role_permission where mt_role_id = t0.id)"));
}
@Test
public void isNotNull_when_ManyToMany_expect_existsSubqueryAndNoJoin() {
ResetBasicData.reset();
Query<Role> query = Ebean.find(Role.class).where().isNotNull("permissions").query();
query.findList();
assertTrue(query.getGeneratedSql().contains("from mt_role t0 where exists (select 1 from mt_role_permission where mt_role_id = t0.id)"));
}
}
@@ -0,0 +1,46 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
public class TestQueryJoinBatchSize extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Order> list = Ebean.find(Order.class)
.fetch("customer", new FetchConfig().queryFirst(3).lazy(2))
//.fetch("orders.details", new FetchConfig().query())
//.fetch("orders.shipments", new FetchConfig().query())
.findList();
for (Order order : list) {
Customer customer = order.getCustomer();
customer.getName();
}
}
// @Test
// public void test() {
//
// ResetBasicData.reset();
//
// Ebean.find(Customer.class)
// .fetch("orders", new FetchConfig().query(3).lazy(2))
// //.fetch("orders.details", new FetchConfig().query())
// //.fetch("orders.shipments", new FetchConfig().query())
// .findList();
//
// }
}
@@ -0,0 +1,31 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Contact;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryJoinMulipleMany extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Order> list = Ebean.find(Order.class).fetch("customer").fetch("customer.contacts").where()
.gt("id", 0).findList();
Assert.assertNotNull(list);
for (Order order : list) {
List<Contact> contacts = order.getCustomer().getContacts();
contacts.size();
}
}
}
@@ -0,0 +1,34 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryMultiManyOrder extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Order> q = Ebean.find(Order.class).fetch("shipments").fetch("details")
.fetch("details.product").fetch("customer").where().gt("id", 0).query();
List<Order> list = q.findList();
String sql = q.getGeneratedSql();
Assert.assertTrue(!list.isEmpty());
Assert.assertTrue(sql.contains("join o_customer "));
Assert.assertFalse(sql.contains("left join contact "));
Assert.assertFalse(sql.contains("left join o_order_detail "));
Assert.assertFalse(sql.contains("left join o_product "));
}
}
@@ -0,0 +1,45 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryNullAssocOne extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Order> q0 = Ebean.find(Order.class).where().eq("customer", null).query();
List<Order> orders = q0.findList();
Assert.assertNotNull(orders);
Assert.assertTrue(q0.getGeneratedSql().contains("where t0.kcustomer_id is null"));
Query<Order> q1 = Ebean.find(Order.class).where().eq("customer.id", null).query();
List<Order> o1 = q1.findList();
Assert.assertTrue(o1.size() == orders.size());
Assert.assertTrue(q1.getGeneratedSql().contains("where t0.kcustomer_id is null"));
Query<Order> q2 = Ebean.find(Order.class).where().isNull("customer").query();
List<Order> o2 = q2.findList();
Assert.assertTrue(o2.size() == orders.size());
Assert.assertTrue(q2.getGeneratedSql().contains("where t0.kcustomer_id is null"));
Query<Order> q3 = Ebean.find(Order.class).where().isNull("customer").query();
List<Order> o3 = q3.findList();
Assert.assertTrue(o3.size() == orders.size());
Assert.assertTrue(q3.getGeneratedSql().contains("where t0.kcustomer_id is null"));
}
}
@@ -0,0 +1,28 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryPathJoinAndOrder extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Customer> list = Ebean.find(Customer.class).select("id,name, status").fetch("contacts")
.order().asc("id").order().desc("contacts.firstName").setMaxRows(3).findList();
Assert.assertNotNull(list);
// can't really assert that the contacts are batch loaded
// via a secondary query join
}
}
@@ -0,0 +1,63 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryPlanCacheRowCount extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class).where().eq("status", Order.Status.NEW).ge("id", 1)
.order().desc("id");
int rc0 = query.findCount();
List<Integer> ids = query.findIds();
Assert.assertEquals(rc0, ids.size());
List<Order> list0 = query.findList();
Assert.assertEquals(rc0, list0.size());
int rc1 = query.findCount();
Assert.assertEquals(rc0, rc1);
List<Integer> ids1 = query.findIds();
Assert.assertEquals(rc0, ids1.size());
List<Order> list1 = query.findList();
Assert.assertEquals(rc0, list1.size());
int idGt = 5;
if (!ids1.isEmpty()) {
Object id = ids.get(0);
idGt = Integer.valueOf("" + id);
}
// should still hit query plan cache
Query<Order> query2 = Ebean.find(Order.class).where().eq("status", Order.Status.NEW)
.ge("id", idGt).order().desc("id");
int rc2 = query2.findCount();
System.out.println("Expection Not same " + rc0 + " != " + rc2);
Assert.assertNotSame(rc0, rc2);
List<Integer> ids2 = query2.findIds();
Assert.assertEquals(rc2, ids2.size());
List<Order> list2 = query2.findList();
Assert.assertEquals(rc2, list2.size());
}
}
@@ -0,0 +1,41 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Contact;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestRefToLazyLoadMany extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Customer> custList = Ebean.find(Customer.class).select("id").findList();
Customer c = custList.get(0);
List<Contact> contacts2 = c.getContacts();
Assert.assertEquals(3, Ebean.getBeanState(c).getLoadedProps().size());
// now lazy load the contacts
contacts2.size();
Customer c2 = Ebean.getReference(Customer.class, c.getId());
// we only "loaded" the contacts BeanList and not all of c2
List<Contact> contacts = c2.getContacts();
// Set<String> loadedProps = Ebean.getBeanState(c2).getLoadedProps();
// assertEquals(1, loadedProps.size());
// now lazy load the contacts
contacts.size();
}
}
@@ -0,0 +1,37 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestRowCount extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class).fetch("details").where().gt("id", 1)
.gt("details.id", 1).order("id desc");
int rc = query.findCount();
List<Object> ids = query.findIds();
List<Order> list = query.findList();
System.out.println(list);
for (Order order : list) {
order.getStatus();
}
Assert.assertEquals("same rc to ids.size() ", rc, ids.size());
Assert.assertEquals("same rc to list.size()", rc, list.size());
}
}
@@ -0,0 +1,138 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.CKeyParent;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.tests.model.basic.Vehicle;
import org.tests.model.basic.VehicleDriver;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.StrictAssertions.assertThat;
public class TestSubQuery extends BaseTestCase {
@Test
public void testId() {
ResetBasicData.reset();
List<Integer> productIds = new ArrayList<>();
productIds.add(3);
Query<Order> sq = Ebean.createQuery(Order.class).select("id").where()
.in("details.product.id", productIds).query();
Ebean.find(Order.class).where().in("id", sq).findList();
}
public void testCompositeKey() {
ResetBasicData.reset();
Query<CKeyParent> sq = Ebean.createQuery(CKeyParent.class).select("id.oneKey")
.setAutoTune(false).where().query();
Query<CKeyParent> pq = Ebean.find(CKeyParent.class).where().in("id.oneKey", sq).query();
pq.findList();
String sql = pq.getGeneratedSql();
String golden = "(t0.one_key) in (select t0.one_key from ckey_parent t0) ";
assertThat(sql).contains(golden);
}
/**
* show that ebean is not using the correct table name in the subquery (sq)
*
* public void testInheritance1() { ResetBasicData.reset();
*
* Query<Vehicle> sq = Ebean.createQuery(Vehicle.class) .select("id")
* .setAutoTune(false) .where() .query();
*
* Query<VehicleDriver> pq = Ebean.find(VehicleDriver.class)
* .where().in("vehicle.id", sq) .query();
*
* pq.findList();
*
* String sql = pq.getGeneratedSql(); System.err.println(sql);
*
* String golden = "(t0.vehicle_id) in (select t0.id from t0.vehicle t0)"; if
* (sql.indexOf(golden) < 0) { System.out.println("failed sql:"+sql);
* fail("golden string not found"); }
*
* }
*/
/**
* show that ebean is adding the discriminator to the list of columns in the
* subquery
*/
public void testInheritance2() {
ResetBasicData.reset();
Query<VehicleDriver> sq = Ebean.createQuery(VehicleDriver.class).select("vehicle")
.setAutoTune(false).where().query();
Query<Vehicle> pq = Ebean.find(Vehicle.class).where().in("id", sq).query();
pq.findList();
String sql = pq.getGeneratedSql();
// TODO: If, after bugfixing, the system still join against vehicle I do not
// know now, in our case, it is not necessary if not
// using it in the where clause
String golden = "(t0.id) in (select t0.vehicle_id from vehicle_driver t0 left join vehicle t1 on t1.id = t0.vehicle_id )";
assertThat(sql).contains(golden);
}
/**
* show that ebean is adding the discriminator to the list of columns in the
* subquery. Second test to make sure that joining is still possible after
* bugfixing testInheritance2.
*/
public void testInheritance3() {
ResetBasicData.reset();
Query<VehicleDriver> sq = Ebean.createQuery(VehicleDriver.class).select("vehicle")
.setAutoTune(false).where().eq("vehicle.licenseNumber", "abc").query();
Query<Vehicle> pq = Ebean.find(Vehicle.class).where().in("id", sq).query();
pq.findList();
String sql = pq.getGeneratedSql();
String golden = "(t0.id) in (select t0.vehicle_id from vehicle_driver t0 left join vehicle t1 on t1.id = t0.vehicle_id where t1.license_number = ? )";
assertThat(sql).contains(golden);
}
/**
* show that ebean is using the wrong column (from the vehicle_driver table
* instead of vehicle) for the selected column in the subquery. In contrast to
* testInheritance2+3 this test forces ebean to "drill down" to the key of the
* relation.
*/
public void testInheritance4() {
ResetBasicData.reset();
Query<VehicleDriver> sq = Ebean.createQuery(VehicleDriver.class).select("vehicle.id")
.setAutoTune(false).where().query();
Query<Vehicle> pq = Ebean.find(Vehicle.class).where().in("id", sq).query();
pq.findList();
String sql = pq.getGeneratedSql();
String golden = "(t0.id) in (select t0.vehicle_id from vehicle_driver t0 left join vehicle t1 on t1.id = t0.vehicle_id )";
assertThat(sql).contains(golden);
}
}
@@ -0,0 +1,25 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
public class TestThreeLevelQueryJoin extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Ebean.find(Customer.class).fetch("orders", new FetchConfig().query())
.fetch("orders.details", new FetchConfig().query())
.fetch("orders.shipments", new FetchConfig().query())
.fetch("shippingAddress", new FetchConfig().query())
.fetch("billingAddress", new FetchConfig().query()).findList();
}
}
@@ -0,0 +1,62 @@
package org.tests.query;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Expr;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.OrderDetail;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.sql.Timestamp;
import static org.assertj.core.api.Assertions.assertThat;
public class TestWhereRawClause extends BaseTestCase {
@Test
public void testRawClauseWithJunction() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.where()
.raw("(status = ? or (orderDate < ? and shipDate is null) or customer.name like ?)",
Order.Status.APPROVED, new Timestamp(System.currentTimeMillis()), "Rob")
.query();
query.findList();
assertThat(query.getGeneratedSql()).contains(" where (t0.status = ? or (t0.order_date < ? and t0.ship_date is null) or t1.name like ?)");
}
@Test
public void testRawClause() {
ResetBasicData.reset();
Ebean.find(OrderDetail.class)
.where()
.not(Expr.eq("id", 1))
.raw("orderQty < shipQty")
.findList();
}
@Test
public void testRawWithBindParams() {
ResetBasicData.reset();
Ebean.find(OrderDetail.class)
.where()
.ne("id", 42)
.raw("orderQty < ?", 100)
.gt("id", 1)
.raw("unitPrice > ? and product.id > ?", 2, 3)
.findList();
}
}
@@ -0,0 +1,128 @@
package org.tests.query.aggregation;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.tevent.TEventMany;
import org.tests.model.tevent.TEventOne;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestAggregationCount extends BaseTestCase {
@BeforeClass
public static void setup() {
TEventOne one = new TEventOne("first");
one.getLogs().add(new TEventMany("all", 1, 10));
one.getLogs().add(new TEventMany("be", 2, 12.2));
one.getLogs().add(new TEventMany("add", 3, 13));
Ebean.save(one);
TEventOne two = new TEventOne("second");
two.getLogs().add(new TEventMany("at", 10, 10));
two.getLogs().add(new TEventMany("add", 30, 13));
two.getLogs().add(new TEventMany("alf", 30, 13));
Ebean.save(two);
}
@Test
public void testBaseSelect() {
Query<TEventOne> query = Ebean.find(TEventOne.class);
List<TEventOne> list = query.findList();
String sql = sqlOf(query, 5);
assertThat(sql).contains("select t0.id, t0.name, t0.version, t0.event_id from tevent_one t0");
for (TEventOne eventOne : list) {
// lazy loading on Aggregation properties
// is not expected to work at this stage
Double totalAmount = eventOne.getTotalAmount();
assertThat(totalAmount).isNull();
}
}
@Test
public void testNonAggregationLazyLoading() {
Query<TEventOne> query = Ebean.find(TEventOne.class).select("id");
List<TEventOne> list = query.findList();
String sql = sqlOf(query, 5);
assertThat(sql).contains("select t0.id from tevent_one t0");
for (TEventOne eventOne : list) {
String name = eventOne.getName();
assertThat(name).isNotNull();
}
}
@Test
public void testFull() {
Query<TEventOne> query2 = Ebean.find(TEventOne.class)
.select("name, count, totalUnits, totalAmount")
.where()
.startsWith("logs.description", "a")
.having()
.ge("count", 1)
.orderBy().asc("name");
List<TEventOne> list = query2.findList();
for (TEventOne eventOne : list) {
System.out.println(eventOne.getId() + " " + eventOne.getName() + " count:" + eventOne.getCount() + " units:" + eventOne.getTotalUnits() + " amount:" + eventOne.getTotalAmount());
}
assertThat(list).isNotEmpty();
String sql = query2.getGeneratedSql();
assertThat(sql).contains("select t0.id c0, t0.name c1, count(u1.id) c2, sum(u1.units) c3, sum(u1.units * u1.amount) c4 from tevent_one t0");
assertThat(sql).contains("from tevent_one t0 join tevent_many u1 on u1.event_id = t0.id ");
assertThat(sql).contains("where u1.description like ? ");
assertThat(sql).contains(" group by t0.id, t0.name having count(u1.id) >= ? order by t0.name");
// invoke lazy loading
Long version = list.get(0).getVersion();
assertThat(version).isNotNull();
}
@Test
public void testSelectOnly() {
Query<TEventOne> query0 = Ebean.find(TEventOne.class)
.select("name, count, totalUnits, totalAmount");
query0.findList();
assertThat(query0.getGeneratedSql()).contains("select t0.id c0, t0.name c1, count(u1.id) c2, sum(u1.units) c3, sum(u1.units * u1.amount) c4 from tevent_one t0");
assertThat(query0.getGeneratedSql()).contains("group by t0.id, t0.name");
}
@Test
public void testSelectWhere() {
Query<TEventOne> query0 = Ebean.find(TEventOne.class)
.select("name, count, totalUnits, totalAmount")
.where().gt("logs.description", "a").query();
query0.findList();
assertThat(query0.getGeneratedSql()).contains("select t0.id c0, t0.name c1, count(u1.id) c2, sum(u1.units) c3, sum(u1.units * u1.amount) c4 from tevent_one t0");
assertThat(query0.getGeneratedSql()).contains("group by t0.id, t0.name");
}
@Test
public void testSelectHavingOrderBy() {
Query<TEventOne> query1 = Ebean.find(TEventOne.class)
.select("name, count, totalUnits, totalAmount")
.having().ge("count", 1)
.orderBy().asc("name");
query1.findList();
assertThat(query1.getGeneratedSql()).contains("having count(u1.id) >= ? order by t0.name");
}
}
@@ -0,0 +1,117 @@
package org.tests.query.autotune;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Address;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.OrderDetail;
import org.tests.model.basic.ResetBasicData;
import org.junit.Ignore;
import org.junit.Test;
import java.util.List;
import java.util.Random;
public class TestAutoTuneProfiling extends BaseTestCase {
@Ignore
@Test
public void test() throws InterruptedException {
ResetBasicData.reset();
for (int i = 0; i < 1; i++) {
execute();
}
collectUsage();
sortOfBusy();
for (int i = 0; i < 10; i++) {
execute();
}
collectUsage();
sortOfBusy();
for (int i = 0; i < 1; i++) {
execute();
}
}
private void sortOfBusy() {
for (int i = 0; i < 90000000; i++) {
new Random().nextLong();
}
}
private void execute() {
useOrderDate();
useOrderDateCustomerName();
useLots();
useLotUntuned();
}
private Order findById(long id) {
return Ebean.find(Order.class)
.select("status, orderDate, shipDate")
.setId(id)
.findUnique();
}
private void useOrderDate() {
Order order = findById(3);
order.getStatus();
order.getShipDate();
}
private void useOrderDateCustomerName() {
Order order = findById(3);
order.getOrderDate();
order.getCustomer().getName();
}
private void useLots() {
Order order = findById(3);
order.getOrderDate();
order.getShipDate();
// order.setShipDate(new Date(System.currentTimeMillis()));
Customer customer = order.getCustomer();
customer.getName();
Address shippingAddress = customer.getShippingAddress();
if (shippingAddress != null) {
shippingAddress.getLine1();
shippingAddress.getCity();
}
}
private void useLotUntuned() {
Order order = findById(3);
List<OrderDetail> details = order.getDetails();
for (OrderDetail detail : details) {
detail.getProduct().getName();
detail.getOrderQty();
detail.getShipQty();
detail.getUnitPrice();
}
Customer customer = order.getCustomer();
customer.getName();
Address billingAddress = customer.getBillingAddress();
if (billingAddress != null) {
billingAddress.getCity();
billingAddress.getLine1();
billingAddress.getLine2();
}
}
private static void collectUsage() {
Ebean.getDefaultServer().getAutoTune().collectProfiling();
}
}
@@ -0,0 +1,110 @@
package org.tests.query.embedded;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheManager;
import io.ebean.cache.ServerCacheStatistics;
import org.tests.model.embedded.EAddress;
import org.tests.model.embedded.EInvoice;
import org.tests.model.embedded.EInvoice.State;
import org.junit.Test;
import java.util.Date;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class TestMultipleEmbeddedLoading extends BaseTestCase {
@Test
public void testSimpleCase() {
// prepare test
EAddress ship = new EAddress();
ship.setStreet("1 Banana St");
ship.setSuburb("Suburb");
ship.setCity("Auckland");
EAddress bill = new EAddress();
bill.setStreet("2 Apple St");
bill.setSuburb("Suburb");
bill.setCity("Auckland");
EInvoice invoice = new EInvoice();
invoice.setInvoiceDate(new Date(System.currentTimeMillis()));
invoice.setState(State.New);
invoice.setShipAddress(ship);
invoice.setBillAddress(bill);
// act: save and fetch
Ebean.save(invoice);
EInvoice invoice2 = Ebean.find(EInvoice.class, invoice.getId());
// assert fetched bean populated as expected
assertEquals(invoice.getId(), invoice2.getId());
assertEquals(invoice.getState(), invoice2.getState());
assertEquals(invoice.getInvoiceDate(), invoice2.getInvoiceDate());
assertEquals("2 Apple St", invoice.getBillAddress().getStreet());
assertEquals("2 Apple St", invoice2.getBillAddress().getStreet());
// act: only update one of the embedded fields
invoice2.getBillAddress().setStreet("3 Pineapple St");
// bean should be dirty
Ebean.save(invoice2);
awaitL2Cache();
EInvoice invoice3 = Ebean.find(EInvoice.class, invoice.getId());
// assert field has updated value
assertEquals("3 Pineapple St", invoice3.getBillAddress().getStreet());
// fetch a partial
EInvoice invoicePartial = Ebean.find(EInvoice.class)
.select("state, date")
.where().idEq(invoice.getId())
.findUnique();
// lazy load of embedded bean
EAddress billAddress = invoicePartial.getBillAddress();
assertNotNull(billAddress);
assertEquals("3 Pineapple St", billAddress.getStreet());
EbeanServer server = Ebean.getServer(null);
ServerCacheManager serverCacheManager = server.getServerCacheManager();
// get cache, clear the cache and statistics
ServerCache beanCache = serverCacheManager.getBeanCache(EInvoice.class);
beanCache.clear();
beanCache.getStatistics(true);
// fetch and load the cache
EInvoice invoice4 = Ebean.find(EInvoice.class, invoice.getId());
assertNotNull(invoice4);
ServerCacheStatistics statistics = beanCache.getStatistics(false);
assertEquals(1, statistics.getSize());
assertEquals(0, statistics.getHitCount());
// fetch out of the cache this time
EInvoice invoice5 = Ebean.find(EInvoice.class, invoice.getId());
assertNotNull(invoice5);
statistics = beanCache.getStatistics(false);
assertEquals(1, statistics.getSize());
assertEquals(1, statistics.getHitCount());
billAddress = invoice5.getBillAddress();
assertNotNull(billAddress);
assertEquals("3 Pineapple St", billAddress.getStreet());
}
}
@@ -0,0 +1,73 @@
package org.tests.query.finder;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestCustomerFinder extends BaseTestCase {
@Test
public void test_ref() {
ResetBasicData.reset();
Customer customer = Customer.find.ref(1);
assertThat(customer.getId()).isEqualTo(1);
}
@Test
public void test_all_byId_byName() {
ResetBasicData.reset();
List<Customer> all = Customer.find.all();
List<Customer> list = Ebean.find(Customer.class).findList();
assertThat(all.size()).isEqualTo(list.size());
Customer customer = all.get(0);
Customer customer1 = Customer.find.byId(customer.getId());
assertThat(customer.getId()).isEqualTo(customer1.getId());
assertThat(customer.getName()).isEqualTo(customer1.getName());
assertThat(Customer.find.db().getName()).isEqualTo(Ebean.getDefaultServer().getName());
}
@Test
public void test_byName_deleteById() {
Customer customer = new Customer();
customer.setName("Newbie-879879897");
Ebean.save(customer);
assertThat(customer.getId()).isNotNull();
Customer customer2 = Customer.find.byName(customer.getName());
assertThat(customer.getId()).isEqualTo(customer2.getId());
assertThat(customer.getName()).isEqualTo(customer2.getName());
Customer.find.deleteById(customer.getId());
awaitL2Cache();
Customer notThere = Customer.find.byId(customer.getId());
assertThat(notThere).isNull();
}
@Test
public void test_nativeSingleAttribute() {
ResetBasicData.reset();
List<String> names = Customer.find.namesStartingWith("F");
assertThat(names).isNotEmpty();
}
}
@@ -0,0 +1,67 @@
package org.tests.query.joins;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.MRole;
import org.tests.model.basic.MUser;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestDisjunctWhereOuterJoin extends BaseTestCase {
@Test
public void test() {
Ebean.beginTransaction();
try {
MRole r1 = new MRole();
r1.setRoleName("role1B");
Ebean.save(r1);
MRole r2 = new MRole();
r2.setRoleName("role2specialB");
Ebean.save(r2);
MRole r3 = new MRole();
r3.setRoleName("role3B");
Ebean.save(r3);
MUser u0 = new MUser();
u0.setUserName("user0B");
u0.addRole(r1);
u0.addRole(r2);
Ebean.save(u0);
MUser u1 = new MUser();
u1.setUserName("user1B");
u1.addRole(r1);
Ebean.save(u1);
Query<MUser> query = Ebean.find(MUser.class)
.where().disjunction()
.eq("roles.roleName", "role2specialB") // user0
.eq("roles.roleName", "role3B") // nobody
.endJunction().query();
List<MUser> list = query.findList();
Assert.assertSame(1, list.size()); // list should contain user0
System.out.println(list);
String sql = query.getGeneratedSql();
Assert.assertTrue(sql.contains("select distinct"));
Assert.assertTrue(sql.contains("left join mrole "));
Assert.assertTrue(sql.contains(".role_name = ?"));
} finally {
Ebean.rollbackTransaction();
}
}
}
@@ -0,0 +1,63 @@
package org.tests.query.joins;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.UUOne;
import org.tests.model.basic.UUTwo;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestDisjunctWhereOuterOnMany extends BaseTestCase {
@Test
public void test() {
Ebean.deleteAll(Ebean.find(UUTwo.class).select("id").findList());
Ebean.deleteAll(Ebean.find(UUOne.class).select("id").findList());
// setup
UUOne master1 = new UUOne();
master1.setName("testDisjOuter_1_name");
UUTwo detail1 = new UUTwo();
detail1.setMaster(master1);
detail1.setName("testDisjOuter_CHILD_1");
UUOne master2 = new UUOne();
master2.setName("testDisjOuter_2_name");
Ebean.save(master1);
Ebean.save(detail1);
Ebean.save(master2);
// Have outer join so that "testDisjOuter_2_name" is found
Query<UUOne> query = Ebean.find(UUOne.class)
.where().disjunction()
.eq("name", "testDisjOuter_2_name")
.eq("comments.name", "testDisjOuter_CHILD_1")
.endJunction()
.query();
List<UUOne> list = query.findList();
int rowCount = query.findCount();
// select distinct t0.id c0, t0.name c1
// from uuone t0
// join uutwo u1 on u1.master_id = t0.id
// left join uutwo t1 on t1.master_id = t0.id
// where (t0.name = ? or u1.name = ? ) ;
// --bind(testDisjOuter_2_name,testDisjOuter_CHILD_1)
Assert.assertEquals(2, list.size());
Assert.assertEquals(2, rowCount);
String expectedSql = "select distinct t0.id, t0.name from uuone t0 left join uutwo u1 on u1.master_id = t0.id where (t0.name = ? or u1.name = ? ) ";
Assert.assertEquals(expectedSql, sqlOf(query, 1));
}
}
@@ -0,0 +1,119 @@
package org.tests.query.joins;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class TestQueryJoinManyNonRoot extends BaseTestCase {
@Test
public void test_manyPredicate() {
ResetBasicData.reset();
LoggedSqlCollector.start();
List<Order> orders = Ebean.find(Order.class)
.select("id, status, orderDate")
.where().gt("details.orderQty", 0)
.findList();
assertTrue(!orders.isEmpty());
List<String> loggedSql = LoggedSqlCollector.stop();
assertEquals(1, loggedSql.size());
assertTrue(loggedSql.get(0).contains("select distinct "));
assertTrue(loggedSql.get(0).contains(" from o_order t0 join o_order_detail u1 on u1.order_id = t0.id "));
}
@Test
public void test_manyNonRoot() {
ResetBasicData.reset();
Query<Order> q = Ebean.find(Order.class)
.fetch("customer")
.fetch("customer.contacts")
.where().gt("id", 0).query();
List<Order> list = q.findList();
String sql = q.getGeneratedSql();
assertTrue(!list.isEmpty());
assertTrue(sql.contains("join o_customer t1 on t1.id "));
assertTrue(sql.contains("left join contact t2 on"));
// select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6,
// t1.id c7, t1.status c8, t1.name c9, t1.smallnote c10, t1.anniversary c11, t1.cretime c12, t1.updtime c13, t1.billing_address_id c14, t1.shipping_address_id c15,
// t2.id c16, t2.first_name c17, t2.last_name c18, t2.phone c19, t2.mobile c20, t2.email c21, t2.cretime c22, t2.updtime c23, t2.customer_id c24, t2.group_id c25
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// left join contact t2 on t2.customer_id = t1.id
// where t0.id > ? ; --bind(0)
}
@Test
public void test_manyRootQueryJoinOrderDetailsFirst() {
ResetBasicData.reset();
Query<Order> q = Ebean.find(Order.class)
.fetch("details")
.fetch("details.product")
.fetch("customer")
.fetch("customer.contacts")
.where().gt("id", 0).query();
List<Order> list = q.findList();
String sql = q.getGeneratedSql();
assertTrue(!list.isEmpty());
assertTrue(sql.contains("join o_customer t1 on t1.id "));
assertTrue(sql.contains("left join o_order_detail "));
assertTrue(sql.contains("left join o_product "));
Assert.assertFalse(sql.contains("left join contact"));
}
@Test
public void test_manyRootQueryJoinCustomerContactsFirst() {
ResetBasicData.reset();
Query<Order> q = Ebean.find(Order.class)
.fetch("customer")
.fetch("customer.contacts")
.fetch("details", new FetchConfig().query(10))
.fetch("details.product")
.where().gt("id", 0).query();
List<Order> list = q.findList();
String sql = q.getGeneratedSql();
for (Order order : list) {
order.getCustomer().getContacts().size();
}
assertTrue(!list.isEmpty());
assertTrue(sql.contains("join o_customer t1 on t1.id "));
assertTrue(sql.contains("left join contact "));
Assert.assertFalse(sql.contains("left join o_order_detail "));
Assert.assertFalse(sql.contains("left join o_product "));
}
}
@@ -0,0 +1,57 @@
package org.tests.query.joins;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.el.ElPropertyValue;
import org.tests.model.basic.Contact;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryJoinQueryNonRoot extends BaseTestCase {
@Test
public void test() {
SpiEbeanServer server = (SpiEbeanServer) Ebean.getServer(null);
BeanDescriptor<Order> d = server.getBeanDescriptor(Order.class);
ElPropertyValue elGetValue = d.getElGetValue("customer.contacts");
Assert.assertTrue(elGetValue.containsMany());
ResetBasicData.reset();
List<Order> list = Ebean.find(Order.class)
.fetch("customer")
.fetch("customer.contacts", "firstName", new FetchConfig().query().lazy(10))
.fetch("customer.contacts.group")
.where().lt("id", 3).findList();
Assert.assertNotNull(list);
Assert.assertTrue(!list.isEmpty());
for (Order order : list) {
List<Contact> contacts = order.getCustomer().getContacts();
for (Contact contact : contacts) {
contact.getFirstName();
}
}
// String oq =
// "find order join customer join customer.contacts join details (+query(4),+lazy(5))";
// Query<Order> q = Ebean.createQuery(Order.class, oq);
// q.setAutoTune(false);
// List<Order> list2 = q.findList();
//
// Assert.assertTrue(list2.size() > 0);
}
}
@@ -0,0 +1,93 @@
package org.tests.query.joins;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
public class TestQueryManyToOneWhereClauseJoin extends BaseTestCase {
/**
* Testing 'where join' created for a ManyToOne relationship.
*/
@Test
public void testJoin() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.where().ilike("customer.name", "rob%")
.query();
query.findList();
//select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7
String expectedSql = "from o_order t0 join o_customer t1 on t1.id = t0.kcustomer_id where lower(t1.name) like ? ";
Assert.assertTrue(query.getGeneratedSql().contains(expectedSql));
// select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// where lower(t1.name) like ? ; --bind(rob%)
}
/**
* Although this is a disjunction it is on a ManyToOne so the 'default' join type is still fine.
*/
@Test
public void testDisjunctionOnManyToOneJoin() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.where().disjunction().ilike("customer.name", "rob%").gt("id", 1).endJunction()
.query();
query.findList();
//select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7
String expectedSql = "from o_order t0 join o_customer t1 on t1.id = t0.kcustomer_id where (lower(t1.name) like ? ";
Assert.assertTrue(query.getGeneratedSql().contains(expectedSql));
// select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// where (lower(t1.name) like ? or t0.id > ? ) ; --bind(rob%,1)
}
/**
* Testing ManyToOne relationship with predicate and fetch.
*/
@Test
public void testWhereAndFetch() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.fetch("customer")
.fetch("customer.contacts")
.where().ilike("customer.name", "rob%")
.query();
query.findList();
String generatedSql = query.getGeneratedSql();
Assert.assertTrue(generatedSql.contains("from o_order t0 join o_customer t1 on t1.id = t0.kcustomer_id"));
Assert.assertTrue(generatedSql.contains("left join contact t2 on t2.customer_id = t1.id"));
Assert.assertTrue(generatedSql.contains("where lower(t1.name) like ?"));
// select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6,
// t1.id c7, t1.status c8, t1.name c9, t1.smallnote c10, t1.anniversary c11, t1.cretime c12, t1.updtime c13, t1.billing_address_id c14, t1.shipping_address_id c15,
// t2.id c16, t2.first_name c17, t2.last_name c18, t2.phone c19, t2.mobile c20, t2.email c21, t2.cretime c22, t2.updtime c23, t2.customer_id c24, t2.group_id c25
// from o_order t0
// join o_customer t1 on t1.id = t0.kcustomer_id
// left join contact t2 on t2.customer_id = t1.id
// where lower(t1.name) like ? ; --bind(rob%)
}
}
@@ -0,0 +1,101 @@
package org.tests.query.lazy;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.OrderDetail;
import org.tests.model.basic.Product;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
public class TestQueryDefaultBatchSize extends BaseTestCase {
@Test
public void test_findEach() {
ResetBasicData.reset();
Ebean.find(Order.class)
.setLazyLoadBatchSize(2)
.findEach(bean -> doStuff(bean));
}
@Test
public void test_findEach_withFetch() {
ResetBasicData.reset();
Ebean.find(Order.class)
.fetch("details", "id")
.fetch("details.product", "sku")
.fetch("customer")
.fetch("customer.contacts")
.setLazyLoadBatchSize(2)
.findEach(bean -> doStuff(bean));
}
@Test
public void test_findList() {
ResetBasicData.reset();
List<Order> orders =
Ebean.find(Order.class)
.setLazyLoadBatchSize(2)
.findList();
for (Order order : orders) {
doStuff(order);
}
}
@Test
public void test_findList_withFetch() {
ResetBasicData.reset();
List<Order> orders =
Ebean.find(Order.class)
.fetch("details", "id")
.fetch("details.product", "sku")
.fetch("customer")
.fetch("customer.contacts")
.setLazyLoadBatchSize(2)
.findList();
for (Order order : orders) {
doStuff(order);
}
}
@Test
public void test_findList_lazyMany() {
ResetBasicData.reset();
List<Order> orders = Ebean.find(Order.class)
.setLazyLoadBatchSize(100)
.findList();
for (Order order : orders) {
List<OrderDetail> details = order.getDetails();
details.size();
for (OrderDetail detail : details) {
Product product = detail.getProduct();
product.getSku();
}
}
}
private void doStuff(Order order) {
// invoke lazy loading
Customer customer = order.getCustomer();
order.getId();
customer.getName();
customer.getContacts().size();
order.getDetails().size();
}
}
@@ -0,0 +1,41 @@
package org.tests.query.orderby;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.OrderBy;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class TestOrderByClear extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.orderBy().asc("orderDate");
OrderBy<Order> orderBy = query.orderBy();
assertTrue(orderBy.containsProperty("orderDate"));
orderBy.clear();
Assert.assertFalse(orderBy.containsProperty("orderDate"));
orderBy.asc("shipDate");
assertTrue(orderBy.containsProperty("shipDate"));
query.findList();
String sql = query.getGeneratedSql();
assertTrue(sql.contains("order by t0.ship_date"));
}
}
@@ -0,0 +1,27 @@
package org.tests.query.orderby;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
public class TestOrderByOnComplex extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class).order().desc("customer");
query.findList();
String sql = query.getGeneratedSql();
Assert.assertTrue(sql.contains("order by t0.kcustomer_id desc"));
}
}
@@ -0,0 +1,123 @@
package org.tests.query.orderby;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.MRole;
import org.tests.model.basic.MUser;
import org.tests.model.basic.MUserType;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
public class TestOrderByWithDistinct extends BaseTestCase {
@Test
public void testOrderByValidation() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.where()
.eq("junk", "blah")
.eq("name", "jim")
.orderBy("id desc,path.that.does.not.exist,contacts.group.name asc");
Set<String> unknownProperties = query.validate();
assertThat(unknownProperties).isNotEmpty();
assertThat(unknownProperties).hasSize(2);
assertThat(unknownProperties).contains("junk", "path.that.does.not.exist");
}
@Test
public void test() {
/*
* Original conversation:
* https://groups.google.com/forum/?fromgroups=#!topic/ebean/uuvi1btdCDQ%5B1-25-false%5D
*
* This test exposes what may be a general problem with columns required by the order by phrase being omitted from the select.
* I'm not sure this exposes all causes of the problem.
*/
MUserType ut = new MUserType("md");
Ebean.save(ut);
MUser user1 = new MUser("one");
user1.setUserType(ut);
Ebean.save(user1);
MUser user2 = new MUser("two");
user2.setUserType(ut);
Ebean.save(user2);
MRole roleA = new MRole("A");
Ebean.save(roleA);
MRole roleB = new MRole("B");
Ebean.save(roleB);
user1.addRole(roleA);
Ebean.save(user1);
user2.addRole(roleB);
Ebean.save(user2);
Query<MUser> query = Ebean.find(MUser.class)
.fetch("userType", "name")
.where()
.eq("roles.roleName", "A")
.orderBy("userType.name, userName");
List<MUser> list = query.findList();
// select distinct t0.userid c0, t0.user_name c1, t1.id c2, t1.name c3
// from muser t0
// left join muser_type t1 on t1.id = t0.user_type_id
// join mrole_muser u1z_ on u1z_.muser_userid = t0.userid
// join mrole u1 on u1.roleid = u1z_.mrole_roleid
// where u1.role_name = ?
// order by t1.name, t0.user_name; --bind(A)
Assert.assertEquals(1, list.size());
Assert.assertEquals(user1, list.get(0));
String generatedSql = query.getGeneratedSql();
Assert.assertTrue(generatedSql.contains("select distinct t0.userid")); // using distinct
Assert.assertTrue(generatedSql.contains("order by t1.name,")); // name in order by
Assert.assertTrue(generatedSql.contains("t1.name"));// name in select
// repeat with slight variation, not sure this really produces a different execution path
// this problem also manifests when autofetch eliminates properties from the select that aren't used in the objects
// still need them to be present for purpose of order by
// so here I'm "simulating" a scenario where autofetch has dropped userType.name
query = Ebean.find(MUser.class)
.setAutoTune(false)
.select("userName")
.fetch("userType", "name")
.where()
.eq("roles.roleName", "A")
.orderBy("userType.name");
list = query.findList();
Assert.assertEquals(1, list.size());
Assert.assertEquals(user1, list.get(0));
// select distinct t0.userid c0, t0.user_name c1, t1.id c2, t1.name c3
// from muser t0
// left join muser_type t1 on t1.id = t0.user_type_id
// join mrole_muser u1z_ on u1z_.muser_userid = t0.userid
// join mrole u1 on u1.roleid = u1z_.mrole_roleid
// where u1.role_name = ?
// order by t1.name; --bind(A)
generatedSql = query.getGeneratedSql();
Assert.assertTrue(generatedSql.contains("select distinct t0.userid")); // using distinct
Assert.assertTrue(generatedSql.contains("order by t1.name")); // name in order by
Assert.assertTrue(generatedSql.contains("t1.name"));// name in select
}
}
@@ -0,0 +1,63 @@
package org.tests.query.orderby;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.junit.Assert;
import org.junit.Test;
public class TestOrderByWithDistinctTake2 extends BaseTestCase {
@Test
public void testRegex() {
String test = "helloasc asc ASC desc DESC boodesc desc ASC";
test = test.replaceAll("(?i)\\b asc\\b|\\b desc\\b", "");
Assert.assertEquals("helloasc boodesc", test);
}
@Test
public void test() {
Query<Customer> query = Ebean.find(Customer.class)
.select("id")
.where().ilike("contacts.firstName", "R%")
.order("name desc");
query.findList();
String generatedSql = sqlOf(query);
// select distinct t0.id c0, t0.name
// from o_customer t0 join contact u1 on u1.customer_id = t0.id
// where lower(u1.first_name) like ?
// order by t0.name; --bind(r%)
Assert.assertTrue("t0.name added to the select clause", generatedSql.contains("select distinct t0.id, t0.name"));
Assert.assertTrue(generatedSql.contains("order by t0.name desc"));
Assert.assertTrue(generatedSql.contains("from o_customer t0 join contact u1 on u1.customer_id = t0.id"));
Assert.assertTrue(generatedSql.contains("where lower(u1.first_name) like ?"));
}
@Test
public void testWithAscAndDesc() {
Query<Customer> query = Ebean.find(Customer.class)
.select("id")
.where().ilike("contacts.firstName", "R%")
.order("name asc,id desc");
query.findList();
String generatedSql = sqlOf(query);
Assert.assertTrue("t0.name added to the select clause", generatedSql.contains("select distinct t0.id, t0.name, t0.id"));
Assert.assertTrue(generatedSql.contains("order by t0.name, t0.id desc"));
Assert.assertTrue(generatedSql.contains("from o_customer t0 join contact u1 on u1.customer_id = t0.id"));
Assert.assertTrue(generatedSql.contains("where lower(u1.first_name) like ?"));
}
}
@@ -0,0 +1,27 @@
package org.tests.query.orderby;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
public class TestOrderByWithFunction extends BaseTestCase {
@Test
public void testWithFunction() {
if (isMsSqlServer()) return;
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class).order("length(name),name");
query.findList();
String sql = query.getGeneratedSql();
Assert.assertTrue(sql.contains("order by length(t0.name)"));
}
}
@@ -0,0 +1,155 @@
package org.tests.query.orderby;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.OrderDetail;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestOrderByWithMany extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
checkWithLazyLoadingOnBuiltInMany();
checkWithBuiltInManyBasic();
checkWithBuiltInMany();
checkAppendId();
checkNone();
checkBoth();
checkPrepend();
checkAlreadyIncluded();
checkAlreadyIncluded2();
}
private void checkWithLazyLoadingOnBuiltInMany() {
LoggedSqlCollector.start();
Query<Order> query = Ebean.find(Order.class);
// a query that ensures we are going to lazy load on the details
List<Order> orders = query.findList();
for (Order order : orders) {
// invoke lazy loading
List<OrderDetail> details = order.getDetails();
details.size();
}
// first one is the main query and others are lazy loading queries
List<String> loggedSql = LoggedSqlCollector.stop();
Assert.assertTrue(loggedSql.size() > 1);
String lazyLoadSql = loggedSql.get(1);
// contains the foreign key back to the parent bean (t0.order_id)
Assert.assertTrue(lazyLoadSql, trimSql(lazyLoadSql, 2).contains("select t0.order_id, t0.id"));
Assert.assertTrue(lazyLoadSql.contains("order by t0.order_id, t0.id, t0.order_qty, t0.cretime desc"));
}
private void checkWithBuiltInManyBasic() {
Query<Order> query = Ebean.find(Order.class).fetch("details");
query.findList();
String sql = query.getGeneratedSql();
Assert.assertTrue(sql.contains("order by t0.id, t1.id asc, t1.order_qty asc, t1.cretime desc"));
}
private void checkWithBuiltInMany() {
Query<Order> query = Ebean.find(Order.class).fetch("details").order().desc("customer.name");
query.findList();
String sql = query.getGeneratedSql();
// t0.id inserted into the middle of the order by
Assert.assertTrue(sql.contains("order by t1.name desc, t0.id, t2.id asc"));
Assert.assertTrue(sql.contains("t2.id asc, t2.order_qty asc, t2.cretime desc"));
}
private void checkAppendId() {
Query<Order> query = Ebean.find(Order.class).fetch("shipments").order().desc("customer.name");
query.findList();
String sql = query.getGeneratedSql();
// append the id to ensure ordering of root level objects
Assert.assertTrue(sql.contains("order by t1.name desc, t0.id"));
}
private void checkNone() {
Query<Order> query = Ebean.find(Order.class).order().desc("customer.name");
query.findList();
String sql = query.getGeneratedSql();
// no need to append id to order by as there is no 'many' included in the
// query
Assert.assertTrue(sql.contains("order by t1.name desc"));
Assert.assertTrue(!sql.contains("order by t1.name desc,"));
}
private void checkBoth() {
Query<Order> query = Ebean.find(Order.class).fetch("shipments").order()
.desc("customer.name, shipments.shipTime");
query.findList();
String sql = query.getGeneratedSql();
// insert id into the middle of the order by
Assert.assertTrue(sql.contains("order by t1.name, t0.id, t2.ship_time desc"));
}
private void checkPrepend() {
Query<Order> query = Ebean.find(Order.class).fetch("shipments").order()
.desc("shipments.shipTime");
query.findList();
String sql = query.getGeneratedSql();
// prepend id in order by
Assert.assertTrue(sql.contains("order by t0.id, t1.ship_time desc"));
}
private void checkAlreadyIncluded() {
Query<Order> query = Ebean.find(Order.class).fetch("shipments").order()
.desc("id, shipments.shipTime");
query.findList();
String sql = query.getGeneratedSql();
// prepend id in order by
Assert.assertTrue(sql.contains("order by t0.id, t1.ship_time desc"));
}
private void checkAlreadyIncluded2() {
Query<Order> query = Ebean.find(Order.class).fetch("shipments").order()
.desc("orderDate, id, shipments.shipTime");
query.findList();
String sql = query.getGeneratedSql();
// prepend id in order by
Assert.assertTrue(sql.contains("order by t0.order_date, t0.id, t1.ship_time desc"));
}
}
@@ -0,0 +1,29 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Truck;
import org.tests.model.basic.Vehicle;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestFindIdsWithInheritance extends BaseTestCase {
@Test
public void testQuery() {
Truck truck = new Truck();
truck.setLicenseNumber("TK123");
Ebean.save(truck);
List<Integer> ids = Ebean.find(Vehicle.class).findIds();
Assert.assertNotNull(ids);
Ebean.delete(truck);
}
}
@@ -0,0 +1,126 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import org.tests.model.basic.EBasic;
import com.sun.management.HotSpotDiagnosticMXBean;
import org.junit.Ignore;
import org.junit.Test;
import javax.management.MBeanServer;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.util.concurrent.atomic.AtomicInteger;
@SuppressWarnings("restriction")
public class TestFindIterateHeapDump extends BaseTestCase {
// All that heap dumping code from :
// https://blogs.oracle.com/sundararajan/entry/programmatically_dumping_heap_from_java
private static final String HOTSPOT_BEAN_NAME = "com.sun.management:type=HotSpotDiagnostic";
/**
* field to store the hotspot diagnostic MBean
*/
private static volatile HotSpotDiagnosticMXBean hotspotMBean;
/**
* Ignore this test generally - run it manually against MySQL specifically for Issue #56.
*/
@Ignore
@Test
public void test() {
EbeanServer server = Ebean.getDefaultServer();
// Transaction transaction = server.beginTransaction();
// try {
// transaction.setBatchMode(true);
// transaction.setBatchSize(20);
// for (int i = 0; i < 20000; i++) {
// EBasic dumbModel = new EBasic();
// dumbModel.setName("Goodbye now");
// server.save(dumbModel);
// }
// transaction.commit();
//
// } finally {
// transaction.end();
// }
//
// if (true) {
// return;
// }
// Intentionally not iterating through the iterator to
final AtomicInteger counter = new AtomicInteger();
server.find(EBasic.class)
.findEach(bean -> {
int count = counter.incrementAndGet();
if (count == 1) {
dumpHeap("heap-dump13-initial.snapshot", true);
}
});
// try {
// while (iterate.hasNext()) {
// EBasic eBasic = iterate.next();
// eBasic.getDescription();
// }
// } finally {
// iterate.close();
// }
String fileName = "heap-dump13.snapshot";
File file = new File(fileName);
if (file.exists())
file.delete();
dumpHeap(fileName, true);
}
static void dumpHeap(String fileName, boolean live) {
// initialize hotspot diagnostic MBean
initHotspotMBean();
try {
hotspotMBean.dumpHeap(fileName, live);
} catch (RuntimeException re) {
throw re;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
/**
* initialize the hotspot diagnostic MBean field
*/
private static void initHotspotMBean() {
if (hotspotMBean == null) {
synchronized (TestFindIterateHeapDump.class) {
if (hotspotMBean == null) {
hotspotMBean = getHotspotMBean();
}
}
}
}
/**
* get the hotspot diagnostic MBean from the ManagementFactory.
*/
private static HotSpotDiagnosticMXBean getHotspotMBean() {
try {
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
return ManagementFactory.newPlatformMXBeanProxy(server, HOTSPOT_BEAN_NAME, HotSpotDiagnosticMXBean.class);
} catch (RuntimeException re) {
throw re;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
}
@@ -0,0 +1,53 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.BeanState;
import io.ebean.Ebean;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class TestFindPartialWithConstructorSetFields extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Order> list = Ebean.find(Order.class)
.setLazyLoadBatchSize(100)
.setUseCache(false)
.select("shipDate")
.findList();
assertTrue(list.size() > 2);
// assert first bean is partially loaded
Order order0 = list.get(0);
BeanState beanState = Ebean.getBeanState(order0);
Set<String> loadedProps = beanState.getLoadedProps();
assertTrue(loadedProps.contains("shipDate"));
assertTrue(!loadedProps.contains("status"));
assertTrue(!loadedProps.contains("orderDate"));
// invoke lazy loading
order0.getStatus();
order0.getOrderDate();
// assert that these beans are fully loaded
for (int i = 1; i < list.size(); i++) {
Order order1 = list.get(1);
beanState = Ebean.getBeanState(order1);
loadedProps = beanState.getLoadedProps();
assertNull(loadedProps);
}
}
}
@@ -0,0 +1,31 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.MNonEnum;
import org.tests.model.basic.MNonUpdPropEntity;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class TestFindWhereUsingEnumerated extends BaseTestCase {
@Test
public void test() {
MNonUpdPropEntity e = new MNonUpdPropEntity();
e.setNonEnum(MNonEnum.END);
e.setName("TheNonEnumIsEnd");
e.setNote("note");
Ebean.save(e);
MNonUpdPropEntity unique = Ebean.find(MNonUpdPropEntity.class).where()
.eq("nonEnum", MNonEnum.END)
.eq("name", "TheNonEnumIsEnd")
.findUnique();
assertThat(unique).isNotNull();
}
}
@@ -0,0 +1,37 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.ExpressionList;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestFormulaWithFindCount extends BaseTestCase {
@Test
public void testFindCount() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
ExpressionList<Order> ex = server.find(Order.class).select("id, status ,totalAmount").where().gt("totalAmount", 1d);
List<Order> list = ex.findList();
for (Order order : list) {
Double amount = order.getTotalAmount();
Assert.assertNotNull(amount);
}
ExpressionList<Order> expressionList = server.find(Order.class).where().gt("totalAmount", 1d);
int rowCount = expressionList.findCount();
Assert.assertEquals(list.size(), rowCount);
}
}
@@ -0,0 +1,74 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import org.tests.model.basic.Order;
import org.tests.model.basic.OrderDetail;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestManyLazyLoadingQuery extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
SpiEbeanServer server = (SpiEbeanServer) Ebean.getServer(null);
BeanDescriptor<Order> descOrder = server.getBeanDescriptor(Order.class);
BeanPropertyAssocMany<?> beanProperty = (BeanPropertyAssocMany<?>) descOrder.getBeanProperty("details");
List<Object> parentIds = new ArrayList<>();
parentIds.add(1);
List<Order> orders =
Ebean.find(Order.class)
.where().lt("id", 4)
.findList();
for (Order order : orders) {
List<OrderDetail> details = order.getDetails();
System.out.println(details.size());
}
// start transaction to keep PC going to lazy query
Ebean.beginTransaction();
try {
Ebean.find(Order.class, 1);
SpiQuery<?> query0 = (SpiQuery<?>) Ebean.find(OrderDetail.class);
query0.setLazyLoadForParents(beanProperty);
beanProperty.addWhereParentIdIn(query0, parentIds, false);
query0.findList();
assertThat(query0.getGeneratedSql()).contains(" from o_order_detail t0 where (t0.order_id) in (");
} finally {
Ebean.endTransaction();
}
List<OrderDetail> details = Ebean.find(OrderDetail.class)
.where().eq("order.id", 1)
.findList();
for (OrderDetail orderDetail : details) {
System.out.println(orderDetail);
}
}
}
@@ -0,0 +1,41 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.MRole;
import org.tests.model.basic.MUser;
import org.junit.Test;
import java.util.List;
public class TestManyToManyLazyLoading extends BaseTestCase {
@Test
public void test() {
createData();
List<MUser> users = Ebean.find(MUser.class).findList();
for (MUser user : users) {
List<MRole> roles = user.getRoles();
roles.size();
}
}
private void createData() {
MRole r0 = new MRole("r0");
MRole r1 = new MRole("r1");
Ebean.save(r0);
Ebean.save(r1);
MUser u0 = new MUser("usr0");
u0.addRole(r0);
u0.addRole(r1);
Ebean.save(u0);
}
}
@@ -0,0 +1,102 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.meta.MetaInfoManager;
import io.ebean.meta.MetaObjectGraphNodeStats;
import io.ebean.meta.MetaQueryPlanStatistic;
import org.tests.model.basic.Address;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.OrderDetail;
import org.tests.model.basic.ResetBasicData;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestObjectGraphNodeStatsCollection extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
EbeanServer server = Ebean.getServer(null);
MetaInfoManager infoManager = server.getMetaInfoManager();
server.find(Order.class).findCount();
infoManager.collectNodeStatistics(true);
infoManager.collectQueryPlanStatistics(true);
runFindOrderQuery(server);
runFindCustomerQuery(server);
List<MetaObjectGraphNodeStats> nodeStatistics = infoManager.collectNodeStatistics(true);
for (MetaObjectGraphNodeStats stat : nodeStatistics) {
stat.toString();
}
List<MetaQueryPlanStatistic> planStatistics = infoManager.collectQueryPlanStatistics(true);
for (MetaQueryPlanStatistic planStatistic : planStatistics) {
planStatistic.getSql();
}
}
private void runFindCustomerQuery(EbeanServer server) {
List<Customer> customers = server.find(Customer.class)
.select("name")
.fetch("contacts")
.findList();
Assert.assertTrue(!customers.isEmpty());
List<Customer> custs = server.find(Customer.class).select("name").findList();
for (Customer customer : custs) {
customer.getShippingAddress();
}
}
private void runFindOrderQuery(EbeanServer server) {
List<Order> orders = server.find(Order.class)
.where().gt("id", 0)
.order().asc("orderDate")
.setMaxRows(40)
.findList();
for (Order order : orders) {
Customer customer = order.getCustomer();
Address billingAddress = customer.getBillingAddress();
if (billingAddress != null) {
billingAddress.getCity();
}
Address shippingAddress = customer.getShippingAddress();
if (shippingAddress != null) {
shippingAddress.getCity();
}
List<OrderDetail> details = order.getDetails();
for (OrderDetail orderDetail : details) {
orderDetail.getUnitPrice();
orderDetail.getProduct().getName();
}
}
}
@Test
public void testFindByIds() {
ResetBasicData.reset();
List<Integer> ids = Ebean.find(Order.class).findIds();
Assert.assertTrue(!ids.isEmpty());
}
}
@@ -0,0 +1,45 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import org.tests.model.map.MpRole;
import org.tests.model.map.MpUser;
import org.junit.Assert;
import org.junit.Test;
import java.util.Map;
public class TestOneToManyAsMap extends BaseTestCase {
@Test
public void test() {
EbeanServer eServer = Ebean.getServer(null);
MpUser u = new MpUser();
eServer.save(u);
MpUser u2 = eServer.find(MpUser.class, u.getId());
Assert.assertNotNull(u2);
u2.setName("Charlie Brown");
MpRole ourl = new MpRole();
ourl.setOrganizationId(47L);
u2.getRoles().put("one", ourl);
eServer.save(u2);
MpUser u3 = eServer.find(MpUser.class, u.getId());
Assert.assertEquals("Charlie Brown", u3.getName());
Map<String, MpRole> listMap = u3.getRoles();
Assert.assertEquals(1, listMap.size());
MpRole mpRole = listMap.get("one");
Assert.assertNotNull(mpRole);
Assert.assertEquals(Long.valueOf(47L), mpRole.getOrganizationId());
Assert.assertEquals("one", mpRole.getCode());
}
}
@@ -0,0 +1,65 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.converstation.Conversation;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryConversationRowCount extends BaseTestCase {
@Test
public void test() {
//"find conversation where club = :clubId and ( ( isPublic = :false and participants.user.id = :userId ) or isPublic = :true ) order by createdAt desc ";
//"find conversation where groupId = :groupId and ( ( open = :false and participants.user.id = :userId ) or open = :true ) order by whenCreated desc ";
Long groupId = 1L;
Long userId = 1L;
Query<Conversation> query = Ebean.find(Conversation.class)
.where().eq("group.id", groupId)
.disjunction()
.conjunction()
.eq("open", false).eq("participants.user.id", userId)
.endJunction()
.eq("open", true)
.endJunction()
.orderBy("whenCreated desc");
query.findList();
String generatedSql = sqlOf(query, 1);
// select distinct t0.id c0, t0.title c1, t0.open c2, t0.version c3, t0.when_created c4, t0.when_updated c5, t0.group_id c6, t0.when_created
// from c_conversation t0
// left join c_participation u1 on u1.conversation_id = t0.id
// where t0.group_id = ? and ((t0.open = ? and u1.user_id = ? ) or t0.open = ? )
// order by t0.when_created desc;
Assert.assertTrue(generatedSql.contains("select distinct t0.id, t0.title, t0.isopen"));
Assert.assertTrue(generatedSql.contains("left join c_participation u1 on u1.conversation_id = t0.id"));
Assert.assertTrue(generatedSql.contains("where t0.group_id = ? and ((t0.isopen = ? and u1.user_id = ? ) or t0.isopen = ? )"));
LoggedSqlCollector.start();
query.findCount();
// select count(*) from (
// select distinct t0.id c0
// from c_conversation t0
// left join c_participation u1 on u1.conversation_id = t0.id
// where t0.group_id = ? and ((t0.open = ? and u1.user_id = ? ) or t0.open = ? )
// ); --bind(1,true,1,true)
List<String> loggedSql = LoggedSqlCollector.stop();
Assert.assertEquals(1, loggedSql.size());
String countSql = trimSql(loggedSql.get(0), 0);
Assert.assertTrue(countSql.contains("select count(*) from ( select distinct t0.id from c_conversation t0 left join c_participation u1 on u1.conversation_id = t0.id where t0.group_id = ? and ((t0.isopen = ? and u1.user_id = ? ) or t0.isopen = ? )"));
}
}
@@ -0,0 +1,105 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
import static junit.framework.TestCase.assertNull;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class TestQueryDistinct extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.setDistinct(true)
.select("name");
List<Customer> customers = query.findList();
String generatedSql = sqlOf(query);
assertThat(generatedSql).contains("select distinct t0.name from o_customer t0");
for (Customer customer : customers) {
EntityBeanIntercept ebi = ((EntityBean) customer)._ebean_getIntercept();
assertTrue(ebi.isDisableLazyLoad());
assertNull(ebi.getPersistenceContext());
// lazy loading disabled
assertNull(customer.getId());
assertNull(customer.getAnniversary());
}
}
@Test
public void test_onWhere() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.where().setDistinct(true)
.select("name");
query.findList();
String generatedSql = sqlOf(query);
assertThat(generatedSql).contains("select distinct t0.name from o_customer t0");
}
@Test
public void testDistinctStatus() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.setDistinct(true)
.select("status")
.where().isNotNull("status").query();
List<Customer> customers = query.findList();
String generatedSql = sqlOf(query);
assertThat(generatedSql).contains("select distinct t0.status from o_customer t0");
for (Customer customer : customers) {
assertNotNull(customer.getStatus());
// lazy loading disabled
assertNull(customer.getId());
assertNull(customer.getAnniversary());
}
}
@Test
public void testPagingQuery_expect_doesNotAddOrderBy() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.setMaxRows(10)
.setDistinct(true)
.select("name");
query.findList();
if (isH2() || isPostgres()) {
String generatedSql = sqlOf(query);
assertThat(generatedSql).contains("select distinct t0.name from o_customer t0 limit 10");
}
}
}
@@ -0,0 +1,35 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestQueryRawExpressionMany extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Integer quantity = 1;
Query<Order> query = Ebean.find(Order.class)
.where().raw("details.orderQty = ?", quantity)
.query();
LoggedSqlCollector.start();
query.findCount();
List<String> sql = LoggedSqlCollector.stop();
assertThat(trimSql(sql.get(0), 1)).contains("select count(*) from ( select distinct t0.id from o_order t0 left join o_order_detail t1 on t1.order_id = t0.id where t1.order_qty = ?)");
}
}
@@ -0,0 +1,94 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryRowCountWithMany extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Long productId = 1L;
Query<Order> query = Ebean.find(Order.class)
.fetch("details")
.where().eq("details.product.id", productId)
.orderBy("cretime asc");
List<Order> list = query.findList();
// select distinct t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t2.name c4, t0.cretime c5, t0.updtime c6, t0.kcustomer_id c7,
// t1.id c8, t1.order_qty c9, t1.ship_qty c10, t1.unit_price c11, t1.cretime c12, t1.updtime c13, t1.order_id c14, t1.product_id c15, t0.cretime, t0.id, t1.id, t1.order_qty, t1.cretime
// from o_order t0
// join o_customer t2 on t2.id = t0.kcustomer_id
// left join o_order_detail t1 on t1.order_id = t0.id
// join o_order_detail u1 on u1.order_id = t0.id
// where t1.id > 0 and u1.product_id = ?
// order by t0.cretime, t0.id, t1.id asc, t1.order_qty asc, t1.cretime desc; --bind(1)
String generatedSql = sqlOf(query, 1);
Assert.assertTrue(generatedSql.contains("select distinct t0.id, t0.status,")); // need the distinct
Assert.assertTrue(generatedSql.contains("left join o_order_detail t1 on t1.order_id = t0.id")); //fetch join
Assert.assertTrue(generatedSql.contains("join o_order_detail u1 on u1.order_id = t0.id")); //predicate join
Assert.assertTrue(generatedSql.contains(" u1.product_id = ?")); // u1 as predicate alias
Assert.assertTrue(generatedSql.contains(" order by t0.cretime"));
int rowCount = query.findCount();
// select count(*) from o_order t0
// left join o_order_detail t1 on t1.order_id = t0.id
// where t1.product_id = ? ; --bind(1)
// select count(*) from (
// select distinct t0.id c0 from o_order t0 join o_order_detail u1 on u1.order_id = t0.id where
// u1.product_id = ?
// ); --bind(1)
List<String> sqlLogged = LoggedSqlCollector.stop();
Assert.assertEquals(list.size(), rowCount);
Assert.assertEquals(2, sqlLogged.size());
Assert.assertTrue(trimSql(sqlLogged.get(1), 1).contains(
"select count(*) from ( select distinct t0.id from o_order t0 join o_order_detail u1 on u1.order_id = t0.id where u1.product_id = ? )"));
}
@Test
public void testWithFirstRowsMaxRows() {
ResetBasicData.reset();
Long productId = 1L;
Query<Order> query = Ebean.find(Order.class)
.fetch("details")
.where().eq("details.product.id", productId)
.setFirstRow(2)
.setMaxRows(20)
.orderBy("cretime asc");
LoggedSqlCollector.start();
query.findCount();
List<String> sqlLogged = LoggedSqlCollector.stop();
Assert.assertEquals(1, sqlLogged.size());
Assert.assertTrue(trimSql(sqlLogged.get(0), 1).contains("select count(*) from ( select distinct t0.id from o_order t0 join o_order_detail u1 on u1.order_id = t0.id where u1.product_id = ? )"));
query.findList();
}
}
@@ -0,0 +1,128 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.sql.Date;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestQuerySingleAttribute extends BaseTestCase {
@Test
public void exampleUsage() {
ResetBasicData.reset();
List<String> names =
Ebean.find(Customer.class)
.setDistinct(true)
.select("name")
.where().eq("status", Customer.Status.NEW)
.orderBy().asc("name")
.setMaxRows(100)
.findSingleAttributeList();
assertThat(names).isNotNull();
}
@Test
public void exampleUsage_otherType() {
ResetBasicData.reset();
List<Date> dates =
Ebean.find(Customer.class)
.setDistinct(true)
.select("anniversary")
.where().isNotNull("anniversary")
.orderBy().asc("anniversary")
.findSingleAttributeList();
assertThat(dates).isNotNull();
}
@Test
public void withOrderBy() {
Query<Customer> query =
Ebean.find(Customer.class)
.setDistinct(true)
.select("name")
.where().eq("status", Customer.Status.NEW)
.orderBy().asc("name")
.setMaxRows(100);
query.findSingleAttributeList();
assertThat(sqlOf(query)).contains("select distinct t0.name from o_customer t0 where t0.status = ? order by t0.name ");
}
@Test
public void basic() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class).select("name");
List<String> names = query.findSingleAttributeList();//String.class);
assertThat(sqlOf(query)).contains("select t0.name from o_customer t0");
assertThat(names).isNotNull();
}
@Test
public void distinctAndWhere() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.setDistinct(true)
.select("name")
.where().eq("status", Customer.Status.NEW)
.query();
List<String> names = query.findSingleAttributeList();
assertThat(sqlOf(query)).contains("select distinct t0.name from o_customer t0 where t0.status = ? ");
assertThat(names).isNotNull();
}
@Test
public void distinctWhereWithJoin() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.setDistinct(true)
.select("name")
.where().eq("status", Customer.Status.NEW)
.istartsWith("billingAddress.city", "auck")
.query();
List<String> names = query.findSingleAttributeList();
assertThat(sqlOf(query)).contains("select distinct t0.name from o_customer t0 left join o_address t1 on t1.id = t0.billing_address_id where t0.status = ? and lower(t1.city) like ?");
assertThat(names).isNotNull();
}
@Test
public void queryPlan_expect_differentPlans() {
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class).select("name");
query.findSingleAttributeList();
assertThat(sqlOf(query)).contains("select t0.name from o_customer t0");
Query<Customer> query2 = Ebean.find(Customer.class).select("name");
query2.findList();
assertThat(sqlOf(query2, 1)).contains("select t0.id, t0.name from o_customer t0");
}
}
@@ -0,0 +1,55 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.selfref.SelfParent;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestSelfParent extends BaseTestCase {
@Test
public void test() {
if (Ebean.find(SelfParent.class).findCount() > 0) {
// only run once
return;
}
SelfParent root = new SelfParent("root", null);
SelfParent child1 = new SelfParent("child1", root);
SelfParent child11 = new SelfParent("child11", child1);
SelfParent child111 = new SelfParent("child111", child11);
SelfParent child12 = new SelfParent("child12", child1);
SelfParent child2 = new SelfParent("child2", root);
SelfParent child21 = new SelfParent("child21", child2);
SelfParent child22 = new SelfParent("child22", child2);
Ebean.save(root);
Ebean.save(child1);
Ebean.save(child11);
Ebean.save(child111);
Ebean.save(child12);
Ebean.save(child2);
Ebean.save(child21);
Ebean.save(child22);
List<SelfParent> roots = Ebean.find(SelfParent.class).where().eq("parent", null).findList();
Assert.assertEquals(1, roots.size());
printNode(roots.get(0));
}
public static void printNode(SelfParent o) {
//System.out.println(o.getName());
for (SelfParent c : o.getChildren()) {
printNode(c);
}
}
}
@@ -0,0 +1,28 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.Expression;
import io.ebean.Query;
import org.tests.model.basic.Customer;
import org.junit.Test;
public class TestSubQueryBinding extends BaseTestCase {
@Test
public void test() {
EbeanServer server = Ebean.getServer(null);
Query<Customer> someCustomerIds = server.find(Customer.class).select("id").where().lt("id", 5).query();
Expression someCustIdsExpression = server.getExpressionFactory().in("id", someCustomerIds);
Query<Customer> query = server.find(Customer.class).where().like("name", "Rob%").not(someCustIdsExpression).query();
query.findList();
}
}
@@ -0,0 +1,59 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestWhereAnnotation extends BaseTestCase {
@Test
public void fetchEager_inFirstQuery() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Customer.class)
.fetch("orders")
.findList();
List<String> loggedSql = LoggedSqlCollector.stop();
Assert.assertEquals(1, loggedSql.size());
String sql = loggedSql.get(0);
Assert.assertTrue(sql.contains("t1.order_date is not null"));
}
@Test
public void fetchLazy_inLazyLoadQuery() {
ResetBasicData.reset();
Ebean.getServerCacheManager().clearAll();
LoggedSqlCollector.start();
List<Customer> customers = Ebean.find(Customer.class)
.findList();
List<Order> orders = customers.get(0).getOrders();
assertThat(orders.size()).isGreaterThan(0);
orders.get(0).getStatus();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(2);
assertThat(loggedSql.get(1)).contains("t0.order_date is not null");
}
}
@@ -0,0 +1,27 @@
package org.tests.query.other;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import org.tests.model.basic.EBasic;
import org.junit.Test;
public class TestWhereLikeWithSlash extends BaseTestCase {
@Test
public void test() {
EBasic basic = new EBasic();
basic.setName("slash\\monkey");
Ebean.save(basic);
Query<EBasic> query = Ebean.find(EBasic.class).where().like("name", "slash\\mon%").query();
query.findList();
// This doesn't work in the latest version of H2 so disable for now.
// Still good on Postgres which was the original issue
//Assert.assertEquals(1, list.size());
}
}
@@ -0,0 +1,58 @@
package org.tests.query.softdelete;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.PagedList;
import org.tests.model.onetoone.album.Cover;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestSoftDeletePagingList extends BaseTestCase {
@Test
public void test() {
List<Cover> list = new ArrayList<>();
list.add(new Cover("SoftDelPaged-1"));
list.add(new Cover("SoftDelPaged-2"));
list.add(new Cover("SoftDelPaged-3"));
Ebean.saveAll(list);
Ebean.delete(list.get(1));
LoggedSqlCollector.start();
PagedList<Cover> pagedList = Ebean.find(Cover.class)
.where().startsWith("s3Url", "SoftDelPaged-")
.setMaxRows(10)
.findPagedList();
int totalRowCount = pagedList.getTotalCount();
List<Cover> resultList = pagedList.getList();
List<String> sql = LoggedSqlCollector.stop();
assertThat(resultList).hasSize(2);
assertThat(totalRowCount).isEqualTo(2);
assertThat(sql).hasSize(2);
assertThat(sql.get(0)).contains("select count(*) from cover t0 where t0.s3url like");
if (isPlatformBooleanNative()) {
assertThat(sql.get(0)).contains("and t0.deleted = false; --bind(SoftDelPaged-%)");
} else {
assertThat(sql.get(0)).contains("and t0.deleted = 0; --bind(SoftDelPaged-%)");
}
assertThat(sql.get(1)).contains("where t0.s3url like ");
if (isPlatformBooleanNative()) {
assertThat(sql.get(1)).contains("and t0.deleted = false order by t0.id");
} else {
assertThat(sql.get(1)).contains("and t0.deleted = 0 order by t0.id");
}
}
}
@@ -0,0 +1,134 @@
package org.tests.query.sqlquery;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.SqlQuery;
import io.ebean.SqlRow;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
public class SqlQueryTests extends BaseTestCase {
@Test
public void firstRowMaxRows() {
ResetBasicData.reset();
SqlQuery sqlQuery = Ebean.createSqlQuery("Select * from o_order");
sqlQuery.setFirstRow(3);
sqlQuery.setMaxRows(10);
LoggedSqlCollector.start();
List<SqlRow> list = sqlQuery.findList();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql.get(0)).contains("Select * from o_order limit 10 offset 3; --bind()");
assertThat(list).isNotEmpty();
}
@Test
public void firstRow() {
if (isPostgres()) {
ResetBasicData.reset();
SqlQuery sqlQuery = Ebean.createSqlQuery("Select * from o_order order by id");
sqlQuery.setFirstRow(3);
LoggedSqlCollector.start();
sqlQuery.findList();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql.get(0)).contains("Select * from o_order order by id offset 3");
}
}
@Test
public void maxRows() {
ResetBasicData.reset();
SqlQuery sqlQuery = Ebean.createSqlQuery("Select * from o_order order by id");
sqlQuery.setMaxRows(10);
LoggedSqlCollector.start();
sqlQuery.findList();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql.get(0)).contains("Select * from o_order order by id limit 10");
}
@Test
public void maxRows_withParam() {
ResetBasicData.reset();
SqlQuery sqlQuery = Ebean.createSqlQuery("select * from o_order where o_order.id > :id order by id ");
sqlQuery.setParameter("id", 3);
sqlQuery.setMaxRows(10);
LoggedSqlCollector.start();
sqlQuery.findList();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql.get(0)).contains("select * from o_order where o_order.id > ? order by id limit 10;");
}
@Test
public void findEachMaxRows() {
ResetBasicData.reset();
SqlQuery sqlQuery = Ebean.createSqlQuery("Select * from o_order");
sqlQuery.setMaxRows(10);
LoggedSqlCollector.start();
sqlQuery.findEach(bean -> bean.get("id"));
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql.get(0)).contains("limit 10");
}
@Test
public void findEach() {
ResetBasicData.reset();
int expectedRows = Ebean.find(Order.class).findCount();
final AtomicInteger count = new AtomicInteger();
SqlQuery sqlQuery = Ebean.createSqlQuery("select * from o_order");
sqlQuery.findEach(bean -> count.incrementAndGet());
assertEquals(expectedRows, count.get());
}
@Test
public void findEachWhile() {
ResetBasicData.reset();
final AtomicInteger count = new AtomicInteger();
SqlQuery sqlQuery = Ebean.createSqlQuery("select * from o_order order by id");
sqlQuery.findEachWhile(bean -> {
count.incrementAndGet();
Integer id = bean.getInteger("id");
return id < 3;
});
assertEquals(3, count.get());
}
}
@@ -0,0 +1,45 @@
package org.tests.query.sqlquery;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import io.ebean.Platform;
import io.ebean.plugin.SpiServer;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestNativeILikeExpression extends BaseTestCase {
@Test
public void test() {
boolean expectNative = isExpectNative();
ResetBasicData.reset();
Query<Customer> query = Ebean.find(Customer.class)
.where().ilike("name", "rob")
.query();
List<Customer> list = query.findList();
if (expectNative) {
assertThat(query.getGeneratedSql()).contains(" from o_customer t0 where t0.name ilike ?");
assertThat(list).isNotEmpty();
}
}
private boolean isExpectNative() {
SpiServer pluginApi = server().getPluginApi();
boolean expressionNativeIlike = pluginApi.getServerConfig().isExpressionNativeIlike();
Platform platform = pluginApi.getDatabasePlatform().getPlatform();
return expressionNativeIlike && platform == Platform.POSTGRES;
}
}