#2067 - Extract ebean-autotune into separate module

This commit is contained in:
rob bygrave
2020-10-08 23:34:56 +13:00
parent 7c36439daf
commit d113ddc525
48 changed files with 700 additions and 424 deletions
+55
View File
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.4.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ebean-autotune</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>12.4.3-SNAPSHOT</version>
</dependency>
<!-- Provided scope to compile with java 11 -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.avaje.composite</groupId>
<artifactId>junit</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.17</version>
<extensions>true</extensions>
<configuration>
<tiles>
<!-- other tiles ... -->
<tile>io.ebean.tile:enhancement:12.4.2</tile>
</tiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -1,4 +1,4 @@
package io.ebeaninternal.server.autotune;
package io.ebeaninternal.server.autotune.service;
import io.ebean.bean.ObjectGraphOrigin;
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
@@ -1,7 +1,6 @@
package io.ebeaninternal.server.autotune.service;
import io.ebean.bean.ObjectGraphOrigin;
import io.ebeaninternal.server.autotune.AutoTuneCollection;
import io.ebeaninternal.server.autotune.model.Autotune;
import io.ebeaninternal.server.autotune.model.Origin;
import io.ebeaninternal.server.autotune.model.ProfileDiff;
@@ -3,10 +3,12 @@ package io.ebeaninternal.server.autotune.service;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.server.autotune.AutoTuneService;
import io.ebeaninternal.server.autotune.AutoTuneServiceProvider;
public class AutoTuneServiceFactory {
public class AutoTuneServiceFactory implements AutoTuneServiceProvider {
public static AutoTuneService create(SpiEbeanServer server, DatabaseConfig config) {
@Override
public AutoTuneService create(SpiEbeanServer server, DatabaseConfig config) {
return new DefaultAutoTuneService(server, config);
}
@@ -4,7 +4,6 @@ import io.ebean.config.AutoTuneConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.autotune.AutoTuneCollection;
import io.ebeaninternal.server.autotune.AutoTuneService;
import io.ebeaninternal.server.autotune.model.Autotune;
import io.ebeaninternal.server.autotune.model.Origin;
@@ -6,7 +6,6 @@ import io.ebean.bean.ObjectGraphOrigin;
import io.ebean.config.AutoTuneConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.autotune.AutoTuneCollection;
import io.ebeaninternal.server.autotune.ProfilingListener;
import io.ebeaninternal.server.deploy.BeanDescriptor;
@@ -5,7 +5,6 @@ import io.ebean.bean.ObjectGraphNode;
import io.ebean.bean.ObjectGraphOrigin;
import io.ebean.text.PathProperties;
import io.ebean.text.PathProperties.Props;
import io.ebeaninternal.server.autotune.AutoTuneCollection;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
@@ -1,7 +1,5 @@
package io.ebeaninternal.server.autotune.service;
import io.ebeaninternal.server.autotune.AutoTuneCollection;
import java.io.Serializable;
import java.util.concurrent.atomic.LongAdder;
@@ -0,0 +1 @@
io.ebeaninternal.server.autotune.service.AutoTuneServiceFactory
@@ -11,7 +11,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class AutoTuneXmlReaderTest {
@Test
public void read_file() throws Exception {
public void read_file() {
File testFile = new File("src/test/resources/autotune/test-autotune.xml");
@@ -20,7 +20,7 @@ public class AutoTuneXmlReaderTest {
}
@Test
public void read_inputStream() throws Exception {
public void read_inputStream() {
InputStream is = getClass().getResourceAsStream("/autotune/test-autotune.xml");
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.autotune.service;
import io.ebean.BaseTestCase;
import io.ebean.DB;
import io.ebean.bean.NodeUsageCollector;
import io.ebean.bean.ObjectGraphNode;
@@ -8,8 +7,9 @@ import io.ebean.bean.ObjectGraphOrigin;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
import org.junit.Test;
import org.tests.autofetch.BaseTestCase;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
//import org.tests.model.basic.ResetBasicData;
import static org.assertj.core.api.Assertions.assertThat;
@@ -102,25 +102,24 @@ public class ProfileOriginTest extends BaseTestCase {
//fetch details (id,orderQty,shipQty,unitPrice)
NodeUsageCollector c = node(null);
c.addUsed("details");
c.addUsed("customer");
po.collectUsageInfo(c);
c = node("details");
c = node("customer");
c.addUsed("id");
c.addUsed("orderQty");
c.addUsed("shipQty");
c.addUsed("unitPrice");
c.addUsed("product");
c.addUsed("name");
c.addUsed("note");
c.addUsed("billingAddress");
po.collectUsageInfo(c);
//fetch details.product (id,name)
c = node("details.product");
c = node("customer.billingAddress");
c.addUsed("id");
c.addUsed("name");
c.addUsed("line1");
po.collectUsageInfo(c);
OrmQueryDetail detail = po.buildDetail(desc);
assertThat(detail.asString()).isEqualTo("fetch details (orderQty,shipQty,unitPrice) fetch details.product (name)");
assertThat(detail.asString()).isEqualTo("fetch customer (name,note) fetch customer.billingAddress (line1)");
}
private NodeUsageCollector node(String path) {
@@ -128,16 +127,16 @@ public class ProfileOriginTest extends BaseTestCase {
return new NodeUsageCollector(node, null);
}
@Test
public void testQueries() {
ResetBasicData.reset();
//DB.createQuery(Order.class, "select (orderDate) fetch customer (billingAddress)").findList();
// we prefer this first query other the second one
DB.createQuery(Order.class, "select (orderDate,customer)").findList();
DB.createQuery(Order.class, "select (orderDate) fetch customer (id)").findList();
}
// @Test
// public void testQueries() {
//
// ResetBasicData.reset();
//
// //DB.createQuery(Order.class, "select (orderDate) fetch customer (billingAddress)").findList();
//
// // we prefer this first query other the second one
// DB.createQuery(Order.class, "select (orderDate,customer)").findList();
// DB.createQuery(Order.class, "select (orderDate) fetch customer (id)").findList();
//
// }
}
@@ -0,0 +1,16 @@
package org.tests.autofetch;
import io.ebean.DB;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.server.deploy.BeanDescriptor;
public class BaseTestCase {
protected SpiEbeanServer spiEbeanServer() {
return (SpiEbeanServer) DB.getDefault();
}
protected <T> BeanDescriptor<T> getBeanDescriptor(Class<T> cls) {
return spiEbeanServer().getBeanDescriptor(cls);
}
}
@@ -0,0 +1,32 @@
package org.tests.autofetch;
//import io.ebean.Ebean;
//import org.tests.model.basic.EBasicClob;
//import java.util.List;
public class MainAutoFetchExcludeLazyLobs {
// public static void main(String[] args) {
//
// EBasicClob a = new EBasicClob();
// a.setName("name 1");
// a.setTitle("a title");
// a.setDescription("not that meaningful");
//
// Ebean.save(a);
//
// List<EBasicClob> list = Ebean.find(EBasicClob.class)
// .setAutoTune(true)
// .findList();
//
// for (EBasicClob bean : list) {
// bean.getName();
// // although we read the description
// // autofetch will not include it later
// bean.getDescription();
// }
//
//
// }
}
@@ -0,0 +1,28 @@
package org.tests.autofetch;
public class MainAutoQueryTune1 {
// public static void main(String[] args) {
//
// ResetBasicData.reset();
//
// MainAutoQueryTune1 me = new MainAutoQueryTune1();
// me.tuneJoin();
// }
//
// private void tuneJoin() {
// List<Order> list = Ebean.find(Order.class)
// .setAutoTune(true)
// .fetch("customer")
// .where()
// .eq("status", Order.Status.NEW)
// .eq("customer.name", "Rob")
// .order().asc("id")
// .findList();
//
// for (Order order : list) {
// order.getId();
// order.getOrderDate();
// }
// }
}
@@ -0,0 +1,172 @@
package org.tests.autofetch;
//import io.ebean.BaseTestCase;
//import io.ebean.Ebean;
//import io.ebean.EbeanServer;
//import io.ebean.Query;
//import io.ebean.bean.EntityBean;
//import io.ebean.bean.EntityBeanIntercept;
//import io.ebean.cache.ServerCacheManager;
//import io.ebeaninternal.api.SpiQuery;
//import io.ebeaninternal.server.autotune.model.Origin;
//import io.ebeaninternal.server.autotune.service.TunedQueryInfo;
//import io.ebeaninternal.server.querydefn.OrmQueryDetail;
//import org.ebeantest.LoggedSqlCollector;
//import org.junit.Assert;
//import org.junit.Test;
//import org.tests.model.basic.Order;
//import org.tests.model.basic.ResetBasicData;
//
//import java.util.List;
//import java.util.Set;
public class TunedQueryInfoTest extends BaseTestCase {
// private void init() {
//
// ResetBasicData.reset();
//
// ServerCacheManager serverCacheManager = Ebean.getServer(null).getServerCacheManager();
// serverCacheManager.clearAll();
// }
//
// @Test
// public void withSelectEmpty() {
//
// init();
//
// OrmQueryDetail tunedDetail = new OrmQueryDetail();
// tunedDetail.select("");
//
// TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
//
// Query<Order> query = server.find(Order.class).setId(1);
//
// tunedInfo.tuneQuery((SpiQuery<?>) query);
//
// Order order = query.findOne();
// EntityBean eb = (EntityBean) order;
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
//
// Assert.assertTrue(ebi.isFullyLoadedBean());
//
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
// Assert.assertNull(loadedPropertyNames);
//
// // invoke lazy loading
// order.getCustomer();
// }
//
// @Test
// public void withSelectSomethingThatDoesNotExist() {
//
// init();
//
// OrmQueryDetail tunedDetail = new OrmQueryDetail();
// tunedDetail.select("somethingThatDoesNotExist");
//
// TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
//
// Query<Order> query = server.find(Order.class).setId(1);
//
// tunedInfo.tuneQuery((SpiQuery<?>) query);
//
// LoggedSqlCollector.start();
//
// Order order = query.findOne();
// EntityBean eb = (EntityBean) order;
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
//
// Assert.assertFalse(ebi.isFullyLoadedBean());
//
// // id and any ToMany relationships
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
// Assert.assertNotNull(loadedPropertyNames);
//
// // invoke lazy loading
// order.getCustomer();
//
// List<String> loggedSql = LoggedSqlCollector.stop();
// Assert.assertEquals(2, loggedSql.size());
//
// Assert.assertTrue(trimSql(loggedSql.get(0), 1).contains("select t0.id, t0.id from o_order t0 where t0.id = ?"));
// Assert.assertTrue(trimSql(loggedSql.get(1), 1).contains("select t0.id, t0.status,"));
// }
//
// private TunedQueryInfo createTunedQueryInfo(OrmQueryDetail tunedDetail) {
// Origin origin = new Origin();
// origin.setDetail(tunedDetail.asString());
// return new TunedQueryInfo(origin);
// }
//
// @Test
// public void withSelectSomeIncludeLazyLoaded() {
//
// init();
//
// OrmQueryDetail tunedDetail = new OrmQueryDetail();
// tunedDetail.select("status, customer");
//
// TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
//
// Query<Order> query = server.find(Order.class).setId(1);
//
// tunedInfo.tuneQuery((SpiQuery<?>) query);
//
// LoggedSqlCollector.start();
//
// Order order = query.findOne();
// EntityBean eb = (EntityBean) order;
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
//
// Assert.assertFalse(ebi.isFullyLoadedBean());
//
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
// Assert.assertNotNull(loadedPropertyNames);
//
// Assert.assertTrue(loadedPropertyNames.contains("status"));
// Assert.assertTrue(loadedPropertyNames.contains("customer"));
//
// // no lazy loading expected here
// order.getCustomer();
//
// List<String> loggedSql = LoggedSqlCollector.stop();
// Assert.assertEquals(1, loggedSql.size());
// }
//
// @Test
// public void withSelectSome() {
//
// init();
//
// OrmQueryDetail tunedDetail = new OrmQueryDetail();
// tunedDetail.select("status");
//
// TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
//
// Query<Order> query = server.find(Order.class).setId(1);
//
// tunedInfo.tuneQuery((SpiQuery<?>) query);
//
// LoggedSqlCollector.start();
//
// Order order = query.findOne();
// EntityBean eb = (EntityBean) order;
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
//
// Assert.assertFalse(ebi.isFullyLoadedBean());
//
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
// Assert.assertNotNull(loadedPropertyNames);
//
// Assert.assertTrue(loadedPropertyNames.contains("status"));
// Assert.assertFalse(loadedPropertyNames.contains("customer"));
//
// // no lazy loading expected here
// order.getCustomer();
//
// List<String> loggedSql = LoggedSqlCollector.stop();
// Assert.assertEquals(2, loggedSql.size());
// }
}
@@ -0,0 +1,69 @@
package org.tests.autofetch;
//import io.ebean.BaseTestCase;
//import io.ebean.Ebean;
//import io.ebean.EbeanServer;
//import io.ebean.Query;
//import io.ebean.bean.EntityBean;
//import io.ebean.bean.EntityBeanIntercept;
//import org.ebeantest.LoggedSqlCollector;
//import org.junit.Assert;
//import org.junit.Test;
//import org.tests.model.basic.Address;
//import org.tests.model.basic.Customer;
//import org.tests.model.basic.ResetBasicData;
import java.util.List;
import java.util.Set;
public class TunedQueryWithNullFetchedBeanTest extends BaseTestCase {
// EbeanServer server = Ebean.getServer(null);
//
// @Test
// public void withFetchOfNullBeanJoin() {
//
// ResetBasicData.reset();
//
// Customer newCustomer = new Customer();
// newCustomer.setName("TestFetchBillingAddress");
// server.save(newCustomer);
//
// Query<Customer> query = server.find(Customer.class)
// .setId(newCustomer.getId())
// .fetch("billingAddress", "id");
//
// LoggedSqlCollector.start();
//
// Customer customer = query.findOne();
// EntityBean eb = (EntityBean) customer;
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
//
// Assert.assertTrue(ebi.isFullyLoadedBean());
//
// // find the internal property index for "billingAddress"
// String[] propNames = eb._ebean_getPropertyNames();
// int pos = 0;
// for (int i = 0; i < propNames.length; i++) {
// if (propNames[i].equals("billingAddress")) {
// pos = i;
// }
// }
//
// // The billing address is loaded (but value null)
// Assert.assertTrue(ebi.isLoadedProperty(pos));
//
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
// Assert.assertNull(loadedPropertyNames);
//
// // no lazy loading expected here, value is null
// Address billingAddress = customer.getBillingAddress();
// Assert.assertNull(billingAddress);
//
// // assert only one query executed
// List<String> loggedSql = LoggedSqlCollector.stop();
// Assert.assertEquals(1, loggedSql.size());
//
// Ebean.delete(newCustomer);
// }
}
@@ -0,0 +1,38 @@
package org.tests.model.basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "address")
public class Address extends BaseModel {
String line1;
String line2;
String city;
public String getLine1() {
return line1;
}
public void setLine1(String line1) {
this.line1 = line1;
}
public String getLine2() {
return line2;
}
public void setLine2(String line2) {
this.line2 = line2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
@@ -0,0 +1,58 @@
package org.tests.model.basic;
import io.ebean.Model;
import io.ebean.annotation.WhenCreated;
import io.ebean.annotation.WhenModified;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
import java.time.Instant;
@MappedSuperclass
public class BaseModel extends Model {
@Id
long id;
@WhenCreated
Instant whenCreated;
@WhenModified
Instant whenModified;
@Version
long version;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Instant getWhenCreated() {
return whenCreated;
}
public void setWhenCreated(Instant whenCreated) {
this.whenCreated = whenCreated;
}
public Instant getWhenModified() {
return whenModified;
}
public void setWhenModified(Instant whenModified) {
this.whenModified = whenModified;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
}
@@ -0,0 +1,41 @@
package org.tests.model.basic;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "o_customer")
public class Customer extends BaseModel {
String name;
String note;
@ManyToOne
Address billingAddress;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Address getBillingAddress() {
return billingAddress;
}
public void setBillingAddress(Address billingAddress) {
this.billingAddress = billingAddress;
}
}
@@ -0,0 +1,60 @@
package org.tests.model.basic;
import io.ebean.Model;
import io.ebean.annotation.WhenModified;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Version;
import java.sql.Timestamp;
import java.time.LocalDate;
@Entity
@Table(name = "orders")
public class Order extends BaseModel {
public enum Status {
NEW,
APPROVED,
SHIPPED,
COMPLETE
}
@Enumerated(EnumType.STRING)
Status status = Status.NEW;
LocalDate orderDate;
@ManyToOne(cascade = CascadeType.PERSIST)
Customer customer;
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public LocalDate getOrderDate() {
return orderDate;
}
public void setOrderDate(LocalDate orderDate) {
this.orderDate = orderDate;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
@@ -0,0 +1,9 @@
ebean.ddl.generate=true
ebean.ddl.run=true
#datasource.default=h2
datasource.db.username=sa
datasource.db.password=
datasource.db.url=jdbc:h2:mem:tests
@@ -0,0 +1,21 @@
<configuration scan="true" scanPeriod="10 seconds">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
<logger name="io.ebean.docker" level="TRACE"/>
<!-- <logger name="io.ebean.DDL" level="DEBUG"/>-->
<!-- <logger name="io.ebean.SQL" level="TRACE"/>-->
<!-- <logger name="io.ebean.TXN" level="TRACE"/>-->
<!-- <logger name="io.ebean.SUM" level="TRACE"/>-->
</configuration>
@@ -0,0 +1,9 @@
package io.ebeaninternal.server.autotune;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.api.SpiEbeanServer;
public interface AutoTuneServiceProvider {
AutoTuneService create(SpiEbeanServer server, DatabaseConfig config);
}
@@ -0,0 +1,34 @@
package io.ebeaninternal.server.autotune;
import io.ebeaninternal.api.SpiQuery;
/**
* Noop service when AutoTuneService is not available.
*/
public class NoAutoTuneService implements AutoTuneService {
@Override
public void startup() {
// do nothing
}
@Override
public boolean tuneQuery(SpiQuery<?> query) {
return false;
}
@Override
public void collectProfiling() {
// do nothing
}
@Override
public void reportProfiling() {
// do nothing
}
@Override
public void shutdown() {
// do nothing
}
}
@@ -33,7 +33,8 @@ import io.ebeaninternal.api.SpiLoggerFactory;
import io.ebeaninternal.api.SpiProfileHandler;
import io.ebeaninternal.dbmigration.DbOffline;
import io.ebeaninternal.server.autotune.AutoTuneService;
import io.ebeaninternal.server.autotune.service.AutoTuneServiceFactory;
import io.ebeaninternal.server.autotune.AutoTuneServiceProvider;
import io.ebeaninternal.server.autotune.NoAutoTuneService;
import io.ebeaninternal.server.cache.CacheManagerOptions;
import io.ebeaninternal.server.cache.DefaultCacheAdapter;
import io.ebeaninternal.server.cache.DefaultServerCacheManager;
@@ -342,7 +343,8 @@ public class InternalConfiguration {
}
AutoTuneService createAutoTuneService(SpiEbeanServer server) {
return AutoTuneServiceFactory.create(server, config);
final AutoTuneServiceProvider provider = config.service(AutoTuneServiceProvider.class);
return provider == null ? new NoAutoTuneService() : provider.create(server, config);
}
DtoQueryEngine createDtoQueryEngine() {
@@ -1,67 +0,0 @@
package org.tests.autofetch;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.embedded.EMain;
import org.tests.model.embedded.Eembeddable;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AutofetchEmbeddedTest extends BaseTestCase {
private final Logger logger = LoggerFactory.getLogger(AutofetchEmbeddedTest.class);
@Test
public void testEmbeddedBeanLazyLoadAndUpdate() {
EMain testBean = new EMain();
testBean.setName("test");
testBean.getEmbeddable().setDescription("test description");
Ebean.save(testBean);
EMain partialBean = Ebean.find(EMain.class).select("version").setId(testBean.getId()).findOne();
logger.info(" -- invoke lazy loading of embedded bean");
Eembeddable embeddable = partialBean.getEmbeddable();
embeddable.setDescription("modified description");
logger.info(" -- update bean");
Ebean.save(partialBean);
}
@Test
public void testEmbeddedBeanQueryTuning() {
// Ebean.getServer(null).getAutoTune().setProfiling(true);
// Ebean.getServer(null).getAutoTune().setQueryTuning(true);
// Ebean.getServer(null).getAutoTune().setProfilingBase(1);
//
// EMain testBean = new EMain();
// testBean.setName("test");
// testBean.getEmbeddable().setDescription("test description");
// Ebean.save(testBean);
//
// //This should not throw an exception
// for (int i = 0; i < 5; i++) {
// Ebean.beginTransaction();
// try {
// List<EMain> result = Ebean.find(EMain.class).setAutoTune(true).findList();
// for (EMain e : result) {
// e.getEmbeddable().setDescription("Test" + i);
// Ebean.save(e);
// }
// Ebean.commitTransaction();
// } finally {
// Ebean.endTransaction();
// logger.debug(Ebean.getServer(null).getAutoTune().collectProfiling());
// }
// }
}
@Test
public void testEmbeddedFetch() {
Ebean.find(EMain.class).fetch("embeddable").findList();
}
}
@@ -1,32 +0,0 @@
package org.tests.autofetch;
import io.ebean.Ebean;
import org.tests.model.basic.EBasicClob;
import java.util.List;
public class MainAutoFetchExcludeLazyLobs {
public static void main(String[] args) {
EBasicClob a = new EBasicClob();
a.setName("name 1");
a.setTitle("a title");
a.setDescription("not that meaningful");
Ebean.save(a);
List<EBasicClob> list = Ebean.find(EBasicClob.class)
.setAutoTune(true)
.findList();
for (EBasicClob bean : list) {
bean.getName();
// although we read the description
// autofetch will not include it later
bean.getDescription();
}
}
}
@@ -1,34 +0,0 @@
package org.tests.autofetch;
import io.ebean.Ebean;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import java.util.List;
public class MainAutoQueryTune1 {
public static void main(String[] args) {
ResetBasicData.reset();
MainAutoQueryTune1 me = new MainAutoQueryTune1();
me.tuneJoin();
}
private void tuneJoin() {
List<Order> list = Ebean.find(Order.class)
.setAutoTune(true)
.fetch("customer")
.where()
.eq("status", Order.Status.NEW)
.eq("customer.name", "Rob")
.order().asc("id")
.findList();
for (Order order : list) {
order.getId();
order.getOrderDate();
}
}
}
@@ -1,174 +0,0 @@
package org.tests.autofetch;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.Query;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.cache.ServerCacheManager;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.autotune.model.Origin;
import io.ebeaninternal.server.autotune.service.TunedQueryInfo;
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
import org.tests.model.basic.Order;
import org.tests.model.basic.ResetBasicData;
import org.ebeantest.LoggedSqlCollector;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import java.util.Set;
public class TunedQueryInfoTest extends BaseTestCase {
EbeanServer server = Ebean.getServer(null);
private void init() {
ResetBasicData.reset();
ServerCacheManager serverCacheManager = Ebean.getServer(null).getServerCacheManager();
serverCacheManager.clearAll();
}
@Test
public void withSelectEmpty() {
init();
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("");
TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
Query<Order> query = server.find(Order.class).setId(1);
tunedInfo.tuneQuery((SpiQuery<?>) query);
Order order = query.findOne();
EntityBean eb = (EntityBean) order;
EntityBeanIntercept ebi = eb._ebean_getIntercept();
Assert.assertTrue(ebi.isFullyLoadedBean());
Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
Assert.assertNull(loadedPropertyNames);
// invoke lazy loading
order.getCustomer();
}
@Test
public void withSelectSomethingThatDoesNotExist() {
init();
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("somethingThatDoesNotExist");
TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
Query<Order> query = server.find(Order.class).setId(1);
tunedInfo.tuneQuery((SpiQuery<?>) query);
LoggedSqlCollector.start();
Order order = query.findOne();
EntityBean eb = (EntityBean) order;
EntityBeanIntercept ebi = eb._ebean_getIntercept();
Assert.assertFalse(ebi.isFullyLoadedBean());
// id and any ToMany relationships
Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
Assert.assertNotNull(loadedPropertyNames);
// invoke lazy loading
order.getCustomer();
List<String> loggedSql = LoggedSqlCollector.stop();
Assert.assertEquals(2, loggedSql.size());
Assert.assertTrue(trimSql(loggedSql.get(0), 1).contains("select t0.id, t0.id from o_order t0 where t0.id = ?"));
Assert.assertTrue(trimSql(loggedSql.get(1), 1).contains("select t0.id, t0.status,"));
}
private TunedQueryInfo createTunedQueryInfo(OrmQueryDetail tunedDetail) {
Origin origin = new Origin();
origin.setDetail(tunedDetail.asString());
return new TunedQueryInfo(origin);
}
@Test
public void withSelectSomeIncludeLazyLoaded() {
init();
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("status, customer");
TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
Query<Order> query = server.find(Order.class).setId(1);
tunedInfo.tuneQuery((SpiQuery<?>) query);
LoggedSqlCollector.start();
Order order = query.findOne();
EntityBean eb = (EntityBean) order;
EntityBeanIntercept ebi = eb._ebean_getIntercept();
Assert.assertFalse(ebi.isFullyLoadedBean());
Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
Assert.assertNotNull(loadedPropertyNames);
Assert.assertTrue(loadedPropertyNames.contains("status"));
Assert.assertTrue(loadedPropertyNames.contains("customer"));
// no lazy loading expected here
order.getCustomer();
List<String> loggedSql = LoggedSqlCollector.stop();
Assert.assertEquals(1, loggedSql.size());
}
@Test
public void withSelectSome() {
init();
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("status");
TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
Query<Order> query = server.find(Order.class).setId(1);
tunedInfo.tuneQuery((SpiQuery<?>) query);
LoggedSqlCollector.start();
Order order = query.findOne();
EntityBean eb = (EntityBean) order;
EntityBeanIntercept ebi = eb._ebean_getIntercept();
Assert.assertFalse(ebi.isFullyLoadedBean());
Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
Assert.assertNotNull(loadedPropertyNames);
Assert.assertTrue(loadedPropertyNames.contains("status"));
Assert.assertFalse(loadedPropertyNames.contains("customer"));
// no lazy loading expected here
order.getCustomer();
List<String> loggedSql = LoggedSqlCollector.stop();
Assert.assertEquals(2, loggedSql.size());
}
}
@@ -1,69 +0,0 @@
package org.tests.autofetch;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.Query;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
import org.ebeantest.LoggedSqlCollector;
import org.junit.Assert;
import org.junit.Test;
import org.tests.model.basic.Address;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import java.util.List;
import java.util.Set;
public class TunedQueryWithNullFetchedBeanTest extends BaseTestCase {
EbeanServer server = Ebean.getServer(null);
@Test
public void withFetchOfNullBeanJoin() {
ResetBasicData.reset();
Customer newCustomer = new Customer();
newCustomer.setName("TestFetchBillingAddress");
server.save(newCustomer);
Query<Customer> query = server.find(Customer.class)
.setId(newCustomer.getId())
.fetch("billingAddress", "id");
LoggedSqlCollector.start();
Customer customer = query.findOne();
EntityBean eb = (EntityBean) customer;
EntityBeanIntercept ebi = eb._ebean_getIntercept();
Assert.assertTrue(ebi.isFullyLoadedBean());
// find the internal property index for "billingAddress"
String[] propNames = eb._ebean_getPropertyNames();
int pos = 0;
for (int i = 0; i < propNames.length; i++) {
if (propNames[i].equals("billingAddress")) {
pos = i;
}
}
// The billing address is loaded (but value null)
Assert.assertTrue(ebi.isLoadedProperty(pos));
Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
Assert.assertNull(loadedPropertyNames);
// no lazy loading expected here, value is null
Address billingAddress = customer.getBillingAddress();
Assert.assertNull(billingAddress);
// assert only one query executed
List<String> loggedSql = LoggedSqlCollector.stop();
Assert.assertEquals(1, loggedSql.size());
Ebean.delete(newCustomer);
}
}
@@ -4,23 +4,20 @@ import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Query;
import io.ebean.cache.ServerCache;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.autotune.model.Origin;
import io.ebeaninternal.server.autotune.service.TunedQueryInfo;
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
import org.tests.model.basic.FeatureDescription;
import org.junit.Assert;
import org.junit.Test;
import org.tests.model.basic.FeatureDescription;
import static org.junit.Assert.assertEquals;
public class TestL2CacheWithSharedBean extends BaseTestCase {
private TunedQueryInfo createTunedQueryInfo(OrmQueryDetail tunedDetail) {
Origin origin = new Origin();
origin.setDetail(tunedDetail.toString());
return new TunedQueryInfo(origin);
}
// private TunedQueryInfo createTunedQueryInfo(OrmQueryDetail tunedDetail) {
// Origin origin = new Origin();
// origin.setDetail(tunedDetail.toString());
// return new TunedQueryInfo(origin);
// }
@Test
public void test() {
@@ -36,11 +33,11 @@ public class TestL2CacheWithSharedBean extends BaseTestCase {
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("name");
TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
// TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
Query<FeatureDescription> query = Ebean.find(FeatureDescription.class).setId(f1.getId());
tunedInfo.tuneQuery((SpiQuery<?>) query);
// tunedInfo.tuneQuery((SpiQuery<?>) query);
query.findOne(); // PUT into cache
+16 -1
View File
@@ -19,11 +19,26 @@
</scm>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<modules>
<module>ebean-core</module>
<module>ebean-autotune</module>
</modules>
</project>