#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,206 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Expr;
import io.ebean.FetchConfig;
import io.ebean.Transaction;
import org.tests.basic.MyTestDataSourcePoolListener;
import org.tests.model.basic.Address;
import org.tests.model.basic.Contact;
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.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class TestBasicLazy extends BaseTestCase {
@Test
public void testQueries() {
ResetBasicData.reset();
Order order = Ebean.find(Order.class).select("totalAmount").setMaxRows(1).order("id")
.findUnique();
Assert.assertNotNull(order);
Customer customer = order.getCustomer();
Assert.assertNotNull(customer);
Assert.assertNotNull(customer.getName());
Address address = customer.getBillingAddress();
Assert.assertNotNull(address);
Assert.assertNotNull(address.getCity());
}
public void test_N1N() {
ResetBasicData.reset();
// safety check to see if our customer we are going to use for the test has
// some contacts
Customer c = Ebean.find(Customer.class).setId(1).findUnique();
Assert.assertNotNull(c.getContacts());
Assert.assertTrue("no contacts on test customer 1", !c.getContacts().isEmpty());
// start transaction so we have a "long running" persistence context
Transaction tx = Ebean.beginTransaction();
try {
List<Order> order = Ebean.find(Order.class).where(Expr.eq("customer.id", 1)).findList();
Assert.assertNotNull(order);
Assert.assertTrue(!order.isEmpty());
Customer customer = order.get(0).getCustomer();
Assert.assertNotNull(customer);
Assert.assertEquals(1, customer.getId().intValue());
// this should lazily fetch the contacts
List<Contact> contacts = customer.getContacts();
Assert.assertNotNull(contacts);
Assert.assertTrue("contacts not lazily fetched", !contacts.isEmpty());
} finally {
tx.commit();
}
}
public void testRaceCondition_Simple() throws Throwable {
ResetBasicData.reset();
Order order = Ebean.find(Order.class).select("totalAmount").setMaxRows(1).order("id")
.findUnique();
Assert.assertNotNull(order);
final Customer customer = order.getCustomer();
Assert.assertNotNull(customer);
Assert.assertTrue(Ebean.getBeanState(customer).isReference());
final Throwable throwables[] = new Throwable[2];
Thread t1 = new Thread() {
@Override
public void run() {
try {
Assert.assertNotNull(customer.getName());
} catch (Throwable e) {
throwables[0] = e;
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
try {
Assert.assertNotNull(customer.getName());
} catch (Throwable e) {
throwables[1] = e;
}
}
};
try {
// prepare for race condition
MyTestDataSourcePoolListener.SLEEP_AFTER_BORROW = 2000;
t1.start();
t2.start();
t1.join();
t2.join();
} finally {
MyTestDataSourcePoolListener.SLEEP_AFTER_BORROW = 0;
}
Assert.assertFalse(Ebean.getBeanState(customer).isReference());
if (throwables[0] != null) {
throw throwables[0];
}
if (throwables[1] != null) {
throw throwables[1];
}
}
private final AtomicBoolean mutex = new AtomicBoolean(false);
private List<Order> orders;
private List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<Throwable>());
private class FetchThread extends Thread {
private int index;
private FetchThread(ThreadGroup tg, int index) {
super(tg, "fetcher-" + index);
this.index = index;
}
@Override
public void run() {
synchronized (mutex) {
System.err.println("** WAIT **");
try {
while (!mutex.get()) {
mutex.wait(100);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
try {
System.err.println("** DO LAZY FETCH **");
orders.get(index).getCustomer().getName();
} catch (Throwable e) {
exceptions.add(e);
}
}
}
public void testRaceCondition_Complex() throws Throwable {
ResetBasicData.reset();
ThreadGroup tg = new ThreadGroup("fetchers");
new FetchThread(tg, 0).start();
new FetchThread(tg, 1).start();
new FetchThread(tg, 2).start();
new FetchThread(tg, 3).start();
new FetchThread(tg, 0).start();
new FetchThread(tg, 1).start();
new FetchThread(tg, 2).start();
new FetchThread(tg, 3).start();
orders = Ebean.find(Order.class).fetch("customer", new FetchConfig().lazy(100)).findList();
Assert.assertTrue(orders.size() >= 4);
try {
MyTestDataSourcePoolListener.SLEEP_AFTER_BORROW = 2000;
synchronized (mutex) {
mutex.set(true);
mutex.notifyAll();
}
while (tg.activeCount() > 0) {
Thread.sleep(100);
}
} finally {
MyTestDataSourcePoolListener.SLEEP_AFTER_BORROW = 0;
}
if (!exceptions.isEmpty()) {
System.err.println("Seen Exceptions:");
for (Throwable exception : exceptions) {
exception.printStackTrace();
}
Assert.fail();
}
}
}
@@ -0,0 +1,28 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.Contact;
import org.tests.model.basic.Customer;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class TestBasicNavOnEmpty extends BaseTestCase {
@Test
public void test() {
Customer c = new Customer();
c.setName("HelloRob");
Ebean.save(c);
c = Ebean.find(Customer.class, c.getId());
List<Contact> contacts = c.getContacts();
Assert.assertEquals(0, contacts.size());
}
}
@@ -0,0 +1,87 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheManager;
import io.ebean.cache.ServerCacheStatistics;
import org.tests.model.basic.UUOne;
import org.avaje.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class TestBatchLazyWithCacheHits extends BaseTestCase {
private UUOne insert(String name) {
UUOne one = new UUOne();
one.setName("testBLWCH" + name);
Ebean.save(one);
return one;
}
@Test
public void testOnCacheHit() {
ArrayList<UUOne> inserted = new ArrayList<>();
String[] names = "A,B,C,D,E,F,G,H,I,J".split(",");
for (String name : names) {
inserted.add(insert(name));
}
ServerCacheManager serverCacheManager = Ebean.getDefaultServer().getServerCacheManager();
ServerCache beanCache = serverCacheManager.getBeanCache(UUOne.class);
beanCache.clear();
UUOne b = Ebean.find(UUOne.class, inserted.get(1).getId());
assertNotNull(b);
UUOne b2 = Ebean.find(UUOne.class, inserted.get(1).getId());
assertNotNull(b2);
ServerCacheStatistics statistics = beanCache.getStatistics(true);
assertEquals(statistics.getHitCount(), 1);
UUOne c = Ebean.find(UUOne.class)
.where().idEq(inserted.get(2).getId())
.findUnique();
assertNotNull(c);
UUOne c2 = Ebean.find(UUOne.class)
.where().idEq(inserted.get(2).getId())
.findUnique();
assertNotNull(c2);
statistics = beanCache.getStatistics(true);
assertEquals(statistics.getHitCount(), 1);
LoggedSqlCollector.start();
List<UUOne> list = Ebean.find(UUOne.class)
//.setDefaultLazyLoadBatchSize(5)
.select("id")
.where().startsWith("name", "testBLWCH")
.order("name")
.findList();
for (UUOne uuOne : list) {
uuOne.getName();
}
list.get(0).getName();
List<String> sql = LoggedSqlCollector.stop();
System.out.println("sql:" + sql);
// batch lazy loading into cache
assertThat(sql).hasSize(2);
assertThat(sql.get(0)).contains("from uuone t0 where t0.name like ?");
assertThat(sql.get(1)).contains("from uuone t0 where t0.id in (?,");
statistics = beanCache.getStatistics(true);
assertThat(statistics.getSize()).isGreaterThan(3);
}
}
@@ -0,0 +1,85 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import org.tests.model.basic.UUOne;
import org.tests.model.basic.UUTwo;
import org.junit.Assert;
import org.junit.Test;
import javax.persistence.EntityNotFoundException;
import java.util.List;
public class TestBatchLazyWithDeleted extends BaseTestCase {
@Test
public void testOnDeleted() {
Ebean.deleteAll(Ebean.find(UUTwo.class).findList());
Ebean.deleteAll(Ebean.find(UUOne.class).findList());
UUOne oneA = new UUOne();
oneA.setName("oneA");
UUOne oneB = new UUOne();
oneB.setName("oneB");
UUTwo two = new UUTwo();
two.setName("two-bld-A");
two.setMaster(oneA);
UUTwo twoB = new UUTwo();
twoB.setName("two-bld-B");
twoB.setMaster(oneA);
UUTwo twoC = new UUTwo();
twoC.setName("two-bld-C");
twoC.setMaster(oneB);
Ebean.save(oneA);
Ebean.save(oneB);
Ebean.save(two);
Ebean.save(twoB);
Ebean.save(twoC);
List<UUTwo> list = Ebean.find(UUTwo.class)
.fetch("master", new FetchConfig().lazy(5))
.where().startsWith("name", "two-bld-")
.order("name")
.findList();
// delete a bean that will be batch lazy loaded but
// is NOT the bean that will invoke the lazy loading
// (in this case it is the second bean in the list).
int deletedCount = Ebean.delete(UUOne.class, oneB.getId());
Assert.assertEquals(1, deletedCount);
for (UUTwo u : list) {
u.getMaster();
//BeanState beanState = Ebean.getBeanState(master);
//Assert.assertTrue(beanState.isReference());
}
// invoke lazy loading on the second 'master' bean
// list.get(2).getMaster().getName();
// invoke lazy loading on the first 'master' bean
list.get(0).getMaster().getName();
// this breaks with IllegalStateException
// because the 2nd UUOne bean is still in 'reference' state
// and has not had its lazyLoadProperty set so it fails as
// it was removed from the "lazy load context" earlier
try {
list.get(2).getMaster().getName();
Assert.assertTrue(false);
} catch (EntityNotFoundException e) {
// this bean was deleted and lazy loading failed
Assert.assertTrue(true);
}
}
}
@@ -0,0 +1,30 @@
package org.tests.batchload;
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.Order.Status;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
public class TestEmptyManyLazyLoad extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Customer c = Ebean.find(Customer.class).findList().get(0);
Order o = new Order();
o.setCustomer(c);
o.setStatus(Status.NEW);
Ebean.save(o);
Order o2 = Ebean.find(Order.class, o.getId());
o2.getDetails().size();
}
}
@@ -0,0 +1,42 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
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.Assert;
import org.junit.Test;
import java.util.List;
public class TestLazyJoin extends BaseTestCase {
@Test
public void testLazyOnNonLoaded() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.select("status")
.fetch("customer", "+lazy(10) name, status")
.fetch("customer.contacts")
.order().asc("id");
List<Order> list = query.findList();
Order order = list.get(0);
Customer customer = order.getCustomer();
// this invokes lazy loading on a property that is
// not one of the selected ones (name, status) ... and
// therefore the lazy load query selects all properties
// in the customer (not just name and status)
Address billingAddress = customer.getBillingAddress();
Assert.assertNotNull(billingAddress);
}
}
@@ -0,0 +1,74 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import org.tests.model.basic.Address;
import org.tests.model.basic.Contact;
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 TestLazyJoin2 extends BaseTestCase {
@Test
public void testLazyOnNonLoaded() {
ResetBasicData.reset();
// This will use 3 SQL queries to build this object graph
List<Order> l0 = Ebean.find(Order.class).select("status, shipDate")
.fetch("details", "orderQty, unitPrice", new FetchConfig().query())
.fetch("details.product", "sku, name")
.fetch("customer", "name", new FetchConfig().query(10))
.fetch("customer.contacts", "firstName, lastName, mobile")
.fetch("customer.shippingAddress", "line1, city").order().asc("id").findList();
Order o0 = l0.get(0);
Customer c0 = o0.getCustomer();
List<Contact> contacts = c0.getContacts();
Assert.assertTrue(!contacts.isEmpty());
// query 1) find order (status, shipDate)
// query 2) find orderDetail (quantity, price) join product (sku, name)
// where order.id in (?,? ...)
// query 3) find customer (name) join contacts (*) join shippingAddress (*)
// where id in (?,?,?,?,?)
List<Order> orders = Ebean.find(Order.class)
// .select("status")
.fetch("customer", new FetchConfig().query(3).lazy(10)).order().asc("id").findList();
// .join("customer.contacts");
// List<Order> list = query.findList();
Order order = orders.get(0);
Customer customer = order.getCustomer();
// this invokes lazy loading on a property that is
// not one of the selected ones (name, status) ... and
// therefore the lazy load query selects all properties
// in the customer (not just name and status)
Address billingAddress = customer.getBillingAddress();
Assert.assertNotNull(billingAddress);
List<Order> list = Ebean.find(Order.class).fetch("customer", "name", new FetchConfig().lazy(5))
.fetch("customer.contacts", "contactName, phone, email").fetch("customer.shippingAddress")
.where().eq("status", Order.Status.NEW).order().asc("id").findList();
Order order2 = list.get(0);
Customer customer2 = order2.getCustomer();
// customer2.getStatus();
String name = customer2.getName();
Assert.assertNotNull(name);
}
}
@@ -0,0 +1,42 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import org.tests.model.basic.Contact;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
public class TestLazyLoadEmptyCollection extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
Customer c = new Customer();
c.setName("lazytest");
Contact con = new Contact("jim", "slim");
c.addContact(con);
Ebean.save(c);
List<Customer> list = Ebean.find(Customer.class)
.fetch("contacts", new FetchConfig().query(0))
.fetch("contacts.notes", new FetchConfig().query(100))
.findList();
for (Customer customer : list) {
List<Contact> contacts = customer.getContacts();
for (Contact contact : contacts) {
contact.getNotes();
}
}
}
}
@@ -0,0 +1,29 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.UUOne;
import org.junit.Assert;
import org.junit.Test;
import javax.persistence.EntityNotFoundException;
import java.util.UUID;
public class TestLazyLoadNonExistantBean extends BaseTestCase {
@Test
public void testSimple() {
UUID uuid = UUID.randomUUID();
UUOne one = Ebean.getReference(UUOne.class, uuid);
try {
// invoke lazy loading
one.getName();
Assert.assertTrue(false);
} catch (EntityNotFoundException e) {
// expecting this
Assert.assertTrue(true);
}
}
}
@@ -0,0 +1,29 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.UUOne;
import org.junit.Assert;
import org.junit.Test;
import javax.persistence.EntityNotFoundException;
import java.util.UUID;
public class TestLazyLoadNonExistentBean extends BaseTestCase {
@Test
public void testSimple() {
UUID uuid = UUID.randomUUID();
UUOne one = Ebean.getReference(UUOne.class, uuid);
try {
// invoke lazy loading
one.getName();
Assert.assertTrue(false);
} catch (EntityNotFoundException e) {
// expecting this
Assert.assertTrue(true);
}
}
}
@@ -0,0 +1,74 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.BeanState;
import io.ebean.Ebean;
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.Assert;
import org.junit.Test;
import java.util.List;
public class TestLoadOnDirty extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
List<Customer> custs = Ebean.find(Customer.class).findList();
Customer customer = Ebean.find(Customer.class).setId(custs.get(0).getId()).select("name")
.setUseCache(false)
.findUnique();
BeanState beanState = Ebean.getBeanState(customer);
Assert.assertTrue(!beanState.isNew());
Assert.assertTrue(!beanState.isDirty());
Assert.assertTrue(!beanState.isNewOrDirty());
Assert.assertNotNull(beanState.getLoadedProps());
customer.setName("dirtyNameProp");
Assert.assertTrue(beanState.isDirty());
Assert.assertTrue(beanState.getChangedProps().contains("name"));
Assert.assertEquals(1, beanState.getChangedProps().size());
EntityBeanIntercept ebi = ((EntityBean) customer)._ebean_getIntercept();
boolean[] dirtyProperties = ebi.getDirtyProperties();
for (int i = 0; i < dirtyProperties.length; i++) {
if (dirtyProperties[i]) {
String dirtyPropertyName = ebi.getProperty(i);
Assert.assertEquals("name", dirtyPropertyName);
}
}
customer.setStatus(Customer.Status.INACTIVE);
Assert.assertTrue(beanState.isDirty());
Assert.assertTrue(beanState.getChangedProps().contains("status"));
Assert.assertTrue(beanState.getChangedProps().contains("name"));
Assert.assertEquals(2, beanState.getChangedProps().size());
}
@Test
public void testDisableLazyLoad() {
ResetBasicData.reset();
List<Customer> custs = Ebean.find(Customer.class).order("id").findList();
Customer customer = Ebean.find(Customer.class)
.setId(custs.get(0).getId())
.select("id")
.setUseCache(false)
.findUnique();
BeanState beanState = Ebean.getBeanState(customer);
beanState.setDisableLazyLoad(true);
Assert.assertNull(customer.getName());
}
}
@@ -0,0 +1,91 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
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.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class TestQueryDisableLazyLoad extends BaseTestCase {
@Test
public void onAssocMany() {
ResetBasicData.reset();
LoggedSqlCollector.start();
List<Order> l0 = Ebean.find(Order.class)
.setDisableLazyLoading(true)
.order().asc("id")
.findList();
assertThat(l0).isNotEmpty();
Order order = l0.get(0);
List<OrderDetail> details = order.getDetails();
assertEquals(details.size(), 0);
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
assertThat(trimSql(loggedSql.get(0), 2)).contains("select t0.id, t0.status, t0.order_date,");
assertThat(loggedSql.get(0)).contains(" from o_order t0 ");
}
@Test
public void onAssocOne() {
ResetBasicData.reset();
LoggedSqlCollector.start();
List<Order> l0 = Ebean.find(Order.class)
.setDisableLazyLoading(true)
.order().asc("id")
.findList();
assertThat(l0).isNotEmpty();
Order order = l0.get(0);
// normally invokes lazy loading
assertNull(order.getCustomer().getStatus());
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
}
@Test
public void onAssocOne_when_partial() {
ResetBasicData.reset();
LoggedSqlCollector.start();
List<Order> l0 = Ebean.find(Order.class)
.setDisableLazyLoading(true)
.fetch("customer", "smallnote")
.order().asc("id")
.findList();
assertThat(l0).isNotEmpty();
Order order = l0.get(0);
// normally invokes lazy loading
assertNull(order.getCustomer().getStatus());
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
}
}
@@ -0,0 +1,65 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.BeanState;
import io.ebean.Ebean;
import io.ebean.Query;
import io.ebean.cache.ServerCache;
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.Assert;
import org.junit.Test;
import java.util.List;
public class TestQueryJoin extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
// Need to make sure the customer cache is cleared for the later
// asserts on the lazy loading
ServerCache custCache = Ebean.getServerCacheManager().getBeanCache(Customer.class);
custCache.clear();
Query<Order> query = Ebean.find(Order.class).select("status")
// .join("details","+query(10)")
.fetch("customer", "+lazy(10) name, status").fetch("customer.contacts").orderBy().asc("id");
// .join("customer.billingAddress");
List<Order> list = query.findList();
// list.get(0).getShipDate();
Order order = list.get(0);
BeanState beanStateOrder = Ebean.getBeanState(order);
Assert.assertNotNull(beanStateOrder.getLoadedProps());
// Assert.assertTrue(beanStateOrder.getLoadedProps().contains("id"));
Assert.assertTrue(beanStateOrder.getLoadedProps().contains("status"));
Assert.assertTrue(beanStateOrder.getLoadedProps().contains("shipments"));
Assert.assertTrue(beanStateOrder.getLoadedProps().contains("customer"));
Customer customer = order.getCustomer();
BeanState beanStateCustomer = Ebean.getBeanState(customer);
Assert.assertTrue(beanStateCustomer.isReference());
customer.getName();
Assert.assertNotNull(beanStateCustomer.getLoadedProps());
Assert.assertTrue(beanStateCustomer.getLoadedProps().contains("name"));
Assert.assertTrue(beanStateCustomer.getLoadedProps().contains("status"));
Assert.assertFalse(beanStateCustomer.getLoadedProps().contains("billingAddress"));
customer.getName();
Address billingAddress = customer.getBillingAddress();
System.out.println(billingAddress);
billingAddress.getLine1();
Assert.assertTrue(!list.isEmpty());
}
}
@@ -0,0 +1,143 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
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.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestQueryJoinToAssocOne extends BaseTestCase {
@Test
public void testQueryJoinOnFullyPopulatedParent() {
ResetBasicData.reset();
LoggedSqlCollector.start();
// This will use 2 SQL queries to build this object graph
List<Order> l0 = Ebean.find(Order.class)
.fetch("details", "orderQty, unitPrice", new FetchConfig().query())
.fetch("details.product", "sku, name")
.findList();
assertThat(l0).isNotEmpty();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(2);
String secondaryQuery = trimSql(loggedSql.get(1), 1);
assertThat(secondaryQuery).contains("select t0.order_id, t0.id,");
assertThat(secondaryQuery).contains(" from o_order_detail t0 left join o_product t1");
assertThat(secondaryQuery).contains(" (t0.order_id) in (?");
assertThat(secondaryQuery).contains(" order by t0.order_id, t0.id");
}
@Test
public void testQueryJoinOnPartiallyPopulatedParent() {
ResetBasicData.reset();
LoggedSqlCollector.start();
// This will use 2 SQL queries to build this object graph
List<Order> l0 = Ebean.find(Order.class)
.select("status, shipDate")
.fetch("details", "orderQty, unitPrice", new FetchConfig().query())
.fetch("details.product", "sku, name")
.findList();
assertThat(l0).isNotEmpty();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(2);
String secondaryQuery = trimSql(loggedSql.get(1), 1);
assertThat(secondaryQuery).contains("select t0.order_id, t0.id,");
assertThat(secondaryQuery).contains(" from o_order_detail t0 left join o_product t1");
assertThat(secondaryQuery).contains(" (t0.order_id) in (?");
assertThat(secondaryQuery).contains(" order by t0.order_id, t0.id");
}
@Test
public void testQueryJoinOnPartiallyPopulatedParent_withLazyLoadingDisabled() {
ResetBasicData.reset();
LoggedSqlCollector.start();
// This will use 2 SQL queries to build this object graph
List<Order> l0 = Ebean.find(Order.class)
.setDisableLazyLoading(true)
.select("status, shipDate")
.fetch("details", "orderQty, unitPrice", new FetchConfig().query())
.fetch("details.product", "sku, name")
.order().asc("id")
.findList();
assertThat(l0).isNotEmpty();
Order order = l0.get(0);
// normally invokes lazy loading
order.getOrderDate();
List<OrderDetail> details = order.getDetails();
OrderDetail orderDetail = details.get(0);
// normally invokes lazy loading
orderDetail.getShipQty();
// normally invokes lazy loading
order.getShipments().size();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(2);
String secondaryQuery = trimSql(loggedSql.get(1), 1);
assertThat(secondaryQuery).contains("select t0.order_id, t0.id,");
assertThat(secondaryQuery).contains(" from o_order_detail t0 left join o_product t1");
assertThat(secondaryQuery).contains(" (t0.order_id) in (?");
assertThat(secondaryQuery).contains(" order by t0.order_id, t0.id");
}
@Test
public void testJoinOnPartiallyPopulatedParent_withLazyLoadingDisabled() {
ResetBasicData.reset();
LoggedSqlCollector.start();
// This will use 2 SQL queries to build this object graph
List<Order> l0 = Ebean.find(Order.class)
.setDisableLazyLoading(true)
.select("status, shipDate")
.fetch("details", "orderQty, unitPrice")//, new FetchConfig().query())
.fetch("details.product", "sku, name")
.findList();
assertThat(l0).isNotEmpty();
Order order = l0.get(0);
// normally invokes lazy loading
order.getOrderDate();
List<OrderDetail> details = order.getDetails();
OrderDetail orderDetail = details.get(0);
// normally invokes lazy loading
orderDetail.getShipQty();
List<String> loggedSql = LoggedSqlCollector.stop();
assertThat(loggedSql).hasSize(1);
String originQuery = trimSql(loggedSql.get(0), 5);
assertThat(originQuery).contains("select t0.id, t0.status, t0.ship_date, t1.id, t1.order_qty, t1.unit_price");
assertThat(originQuery).contains(" from o_order t0 left join o_order_detail t1 ");
}
}
@@ -0,0 +1,31 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import org.tests.model.basic.Customer;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class TestSecondQueryNoRows extends BaseTestCase {
@Test
public void test() {
Customer cnew = new Customer();
cnew.setName("testSecQueryNoRows");
Ebean.save(cnew);
Customer c = Ebean.find(Customer.class)
.setAutoTune(false)
.setId(cnew.getId())
.fetch("contacts", new FetchConfig().query())
.findUnique();
assertNotNull(c);
assertEquals(0, c.getContacts().size());
}
}
@@ -0,0 +1,161 @@
package org.tests.batchload;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.FetchConfig;
import io.ebean.Query;
import io.ebeaninternal.api.SpiQuery;
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 TestSecondaryQueries extends BaseTestCase {
@Test
public void fetchQuery() {
ResetBasicData.reset();
LoggedSqlCollector.start();
Ebean.find(Order.class)
.select("status")
.fetchQuery("customer", "name")
.findList();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(2);
assertThat(trimSql(sql.get(0), 2)).contains("select t0.id, t0.status, t0.kcustomer_id from o_order t0");
assertThat(trimSql(sql.get(1), 2)).contains("select t0.id, t0.name from o_customer t0 where t0.id in");
}
@Test
public void fetchLazy() {
ResetBasicData.reset();
LoggedSqlCollector.start();
List<Order> orders = Ebean.find(Order.class)
.select("status")
.fetchLazy("customer", "name")
.setMaxRows(10)
.setUseCache(false)
.findList();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(1);
assertThat(trimSql(sql.get(0), 2)).contains("select t0.id, t0.status, t0.kcustomer_id from o_order t0");
LoggedSqlCollector.start();
// invoke lazy loading
for (Order order : orders) {
order.getCustomer().getName();
}
sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(1);
assertThat(trimSql(sql.get(0), 1)).contains("select t0.id, t0.name from o_customer t0 where t0.id in");
}
@Test
public void testSecQueryOneToMany() {
ResetBasicData.reset();
Order testOrder = ResetBasicData.createOrderCustAndOrder("testSecQry10");
Integer custId = testOrder.getCustomer().getId();
Query<Customer> query = Ebean.find(Customer.class)
.select("name")
.fetch("contacts", "+query")
.setId(custId);
SpiQuery<?> spiQuery = (SpiQuery<?>) query;
spiQuery.setLogSecondaryQuery(true);
Customer cust = query.findUnique();
Assert.assertNotNull(cust);
String generatedSql = query.getGeneratedSql();
Assert.assertTrue(generatedSql.contains("from o_customer t0 where t0.id = ?"));
List<SpiQuery<?>> loggedSecondaryQueries = spiQuery.getLoggedSecondaryQueries();
Assert.assertEquals(1, loggedSecondaryQueries.size());
SpiQuery<?> secondaryQuery = loggedSecondaryQueries.get(0);
String secondarySql = secondaryQuery.getGeneratedSql();
Assert.assertTrue(secondarySql.contains("from contact t0 where (t0.customer_id) in (?)"));
}
@Test
public void testManyToOneWithManyPlusOneToMany() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.select("status")
.fetch("customer", "name, status", new FetchConfig().query())
.fetch("customer.contacts")
.fetch("details", new FetchConfig().query())
.where().eq("status", Order.Status.NEW)
.query();
// .fetch("customer", "+query name, status")
// .fetch("details", "+query(10)")
SpiQuery<?> spiQuery = (SpiQuery<?>) query;
spiQuery.setLogSecondaryQuery(true);
List<Order> list = query.findList();
Assert.assertTrue(!list.isEmpty());
for (Order order : list) {
order.getCustomer().getStatus();
}
String generatedSql = sqlOf(spiQuery, 2);
//select t0.id c0, t0.status c1, t0.kcustomer_id c2 from o_order t0 where t0.status = ? ; --bind(NEW)
Assert.assertEquals("select t0.id, t0.status, t0.kcustomer_id from o_order t0 where t0.status = ? ", generatedSql);
List<SpiQuery<?>> secondaryQueries = spiQuery.getLoggedSecondaryQueries();
Assert.assertEquals(2, secondaryQueries.size());
SpiQuery<?> custSecondaryQuery = secondaryQueries.get(0);
String custSecondarySql = custSecondaryQuery.getGeneratedSql();
// select t0.id c0, t0.name c1, t0.status c2,
// t1.id c3, t1.first_name c4, t1.last_name c5, t1.phone c6, t1.mobile c7, t1.email c8, t1.cretime c9, t1.updtime c10, t1.customer_id c11, t1.group_id c12
// from o_customer t0
// left join contact t1 on t1.customer_id = t0.id
// where t0.id = ? order by t0.id; --bind(1)
Assert.assertTrue(custSecondarySql.contains("from o_customer t0 "));
Assert.assertTrue(custSecondarySql.contains("left join contact t1 on t1.customer_id = t0.id "));
Assert.assertTrue(custSecondarySql.contains("where t0.id "));
SpiQuery<?> orderDetailsSecondaryQuery = secondaryQueries.get(1);
String ordSecondarySql = orderDetailsSecondaryQuery.getGeneratedSql();
// select ...
// from o_order_detail t0
// where (t0.order_id) in (?,?,?,?,?) ; --bind(1,4,1,1,1)
Assert.assertTrue(ordSecondarySql.contains(" from o_order_detail t0 where t0.id > 0 and (t0.order_id) in (?"));
}
}