mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaccc47f2f |
@@ -3,13 +3,24 @@ package io.ebean.meta;
|
|||||||
/**
|
/**
|
||||||
* Request used to capture query plans.
|
* Request used to capture query plans.
|
||||||
*/
|
*/
|
||||||
public class QueryPlanRequest {
|
public final class QueryPlanRequest {
|
||||||
|
|
||||||
private long since;
|
private long since;
|
||||||
|
|
||||||
private int maxCount;
|
private final int maxCount;
|
||||||
|
|
||||||
private long maxTimeMillis;
|
private final long maxTimeMillis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create with the max number of plans and max capture time.
|
||||||
|
*
|
||||||
|
* @param maxCount The maximum number of plans to capture
|
||||||
|
* @param maxTimeMillis The maximum time after which we stop capturing more plans
|
||||||
|
*/
|
||||||
|
public QueryPlanRequest(int maxCount, long maxTimeMillis) {
|
||||||
|
this.maxCount = maxCount;
|
||||||
|
this.maxTimeMillis = maxTimeMillis;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the epoch time in millis for minimum bind capture time.
|
* Return the epoch time in millis for minimum bind capture time.
|
||||||
@@ -39,16 +50,6 @@ public class QueryPlanRequest {
|
|||||||
return maxCount;
|
return maxCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the maximum number of plans to capture.
|
|
||||||
* <p>
|
|
||||||
* Use this to limit how much query plan capturing is done as query
|
|
||||||
* plan capture is actual database load.
|
|
||||||
*/
|
|
||||||
public void maxCount(int maxCount) {
|
|
||||||
this.maxCount = maxCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the maximum amount of time we want to use to capture plans.
|
* Return the maximum amount of time we want to use to capture plans.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -57,15 +58,4 @@ public class QueryPlanRequest {
|
|||||||
public long maxTimeMillis() {
|
public long maxTimeMillis() {
|
||||||
return maxTimeMillis;
|
return maxTimeMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the maximum amount of time we want to use to capture plans.
|
|
||||||
* <p>
|
|
||||||
* Query plan collection will stop once this time is exceeded. We use
|
|
||||||
* this to ensure the query plan capture does not use excessive amount
|
|
||||||
* of time - put too much load on the database.
|
|
||||||
*/
|
|
||||||
public void maxTimeMillis(long maxTimeMillis) {
|
|
||||||
this.maxTimeMillis = maxTimeMillis;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ import java.util.List;
|
|||||||
|
|
||||||
final class NoopQueryPlanManager implements QueryPlanManager {
|
final class NoopQueryPlanManager implements QueryPlanManager {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startPlanCapture() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDefaultThreshold(long thresholdMicros) {
|
public void setDefaultThreshold(long thresholdMicros) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ public interface QueryPlanManager {
|
|||||||
|
|
||||||
QueryPlanManager NOOP = new NoopQueryPlanManager();
|
QueryPlanManager NOOP = new NoopQueryPlanManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start background capture of query plans if enabled.
|
||||||
|
*/
|
||||||
|
void startPlanCapture();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the global default threshold used when new query plans are created.
|
* Update the global default threshold used when new query plans are created.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.core;
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
import io.ebean.meta.*;
|
import io.ebean.meta.*;
|
||||||
|
import io.ebeaninternal.api.QueryPlanManager;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@@ -11,11 +12,13 @@ import java.util.function.Function;
|
|||||||
final class DefaultMetaInfoManager implements MetaInfoManager {
|
final class DefaultMetaInfoManager implements MetaInfoManager {
|
||||||
|
|
||||||
private final DefaultServer server;
|
private final DefaultServer server;
|
||||||
|
private final QueryPlanManager queryPlanManager;
|
||||||
private final Function<String, String> naming;
|
private final Function<String, String> naming;
|
||||||
|
|
||||||
DefaultMetaInfoManager(DefaultServer server, Function<String, String> naming) {
|
DefaultMetaInfoManager(DefaultServer server, QueryPlanManager queryPlanManager) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.naming = naming;
|
this.naming = server.config().getMetricNaming();
|
||||||
|
this.queryPlanManager = queryPlanManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -25,7 +28,7 @@ final class DefaultMetaInfoManager implements MetaInfoManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MetaQueryPlan> queryPlanCollectNow(QueryPlanRequest request) {
|
public List<MetaQueryPlan> queryPlanCollectNow(QueryPlanRequest request) {
|
||||||
return server.queryPlanCollectNow(request);
|
return queryPlanManager.collect(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ import java.sql.Statement;
|
|||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@@ -105,7 +104,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
private final EncryptKeyManager encryptKeyManager;
|
private final EncryptKeyManager encryptKeyManager;
|
||||||
private final SpiJsonContext jsonContext;
|
private final SpiJsonContext jsonContext;
|
||||||
private final DocumentStore documentStore;
|
private final DocumentStore documentStore;
|
||||||
private final MetaInfoManager metaInfoManager;
|
private final DefaultMetaInfoManager metaInfoManager;
|
||||||
private final CurrentTenantProvider currentTenantProvider;
|
private final CurrentTenantProvider currentTenantProvider;
|
||||||
private final SpiLogManager logManager;
|
private final SpiLogManager logManager;
|
||||||
private final PersistenceContextScope defaultPersistenceContextScope;
|
private final PersistenceContextScope defaultPersistenceContextScope;
|
||||||
@@ -156,8 +155,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
DocStoreIntegration docStoreComponents = config.createDocStoreIntegration(this);
|
DocStoreIntegration docStoreComponents = config.createDocStoreIntegration(this);
|
||||||
this.transactionManager = config.createTransactionManager(this, docStoreComponents.updateProcessor());
|
this.transactionManager = config.createTransactionManager(this, docStoreComponents.updateProcessor());
|
||||||
this.documentStore = docStoreComponents.documentStore();
|
this.documentStore = docStoreComponents.documentStore();
|
||||||
this.queryPlanManager = config.initQueryPlanManager(transactionManager);
|
this.queryPlanManager = config.initQueryPlanManager(this, transactionManager);
|
||||||
this.metaInfoManager = new DefaultMetaInfoManager(this, this.config.getMetricNaming());
|
this.metaInfoManager = new DefaultMetaInfoManager(this, queryPlanManager);
|
||||||
this.serverPlugins = config.getPlugins();
|
this.serverPlugins = config.getPlugins();
|
||||||
this.ddlGenerator = config.initDdlGenerator(this);
|
this.ddlGenerator = config.initDdlGenerator(this);
|
||||||
this.scriptRunner = new DScriptRunner(this);
|
this.scriptRunner = new DScriptRunner(this);
|
||||||
@@ -326,31 +325,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
migrationRunner.loadProperties(config.getProperties());
|
migrationRunner.loadProperties(config.getProperties());
|
||||||
migrationRunner.run(config.getDataSource());
|
migrationRunner.run(config.getDataSource());
|
||||||
}
|
}
|
||||||
startQueryPlanCapture();
|
queryPlanManager.startPlanCapture();
|
||||||
}
|
|
||||||
|
|
||||||
private void startQueryPlanCapture() {
|
|
||||||
if (config.isQueryPlanCapture()) {
|
|
||||||
long secs = config.getQueryPlanCapturePeriodSecs();
|
|
||||||
if (secs > 10) {
|
|
||||||
log.log(INFO, "capture query plan enabled, every {0}secs", secs);
|
|
||||||
backgroundExecutor.scheduleWithFixedDelay(this::collectQueryPlans, secs, secs, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void collectQueryPlans() {
|
|
||||||
QueryPlanRequest request = new QueryPlanRequest();
|
|
||||||
request.maxCount(config.getQueryPlanCaptureMaxCount());
|
|
||||||
request.maxTimeMillis(config.getQueryPlanCaptureMaxTimeMillis());
|
|
||||||
|
|
||||||
// obtains query explain plans ...
|
|
||||||
List<MetaQueryPlan> plans = metaInfoManager.queryPlanCollectNow(request);
|
|
||||||
QueryPlanListener listener = config.getQueryPlanListener();
|
|
||||||
if (listener == null) {
|
|
||||||
listener = DefaultQueryPlanListener.INSTANT;
|
|
||||||
}
|
|
||||||
listener.process(new QueryPlanCapture(this, plans));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -575,12 +575,12 @@ public final class InternalConfiguration {
|
|||||||
return new DefaultServerCacheManager(builder);
|
return new DefaultServerCacheManager(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryPlanManager initQueryPlanManager(TransactionManager transactionManager) {
|
public QueryPlanManager initQueryPlanManager(DefaultServer server, TransactionManager transactionManager) {
|
||||||
if (!config.isQueryPlanEnable()) {
|
if (!config.isQueryPlanEnable()) {
|
||||||
return QueryPlanManager.NOOP;
|
return QueryPlanManager.NOOP;
|
||||||
}
|
}
|
||||||
long threshold = config.getQueryPlanThresholdMicros();
|
long threshold = config.getQueryPlanThresholdMicros();
|
||||||
return new CQueryPlanManager(transactionManager, threshold, queryPlanLogger(databasePlatform.platform()), extraMetrics);
|
return new CQueryPlanManager(server, transactionManager, threshold, queryPlanLogger(databasePlatform.platform()), extraMetrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
package io.ebeaninternal.server.query;
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
|
import io.ebean.config.QueryPlanCapture;
|
||||||
|
import io.ebean.config.QueryPlanListener;
|
||||||
import io.ebean.meta.MetaQueryPlan;
|
import io.ebean.meta.MetaQueryPlan;
|
||||||
import io.ebean.meta.QueryPlanRequest;
|
import io.ebean.meta.QueryPlanRequest;
|
||||||
import io.ebean.metric.TimedMetric;
|
import io.ebean.metric.TimedMetric;
|
||||||
import io.ebeaninternal.api.*;
|
import io.ebeaninternal.api.*;
|
||||||
|
import io.ebeaninternal.server.core.DefaultServer;
|
||||||
import io.ebeaninternal.server.transaction.TransactionManager;
|
import io.ebeaninternal.server.transaction.TransactionManager;
|
||||||
import io.ebeaninternal.server.bind.capture.BindCapture;
|
import io.ebeaninternal.server.bind.capture.BindCapture;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
import static java.lang.System.Logger.Level.ERROR;
|
import static java.lang.System.Logger.Level.ERROR;
|
||||||
|
import static java.lang.System.Logger.Level.INFO;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
|
||||||
public final class CQueryPlanManager implements QueryPlanManager {
|
public final class CQueryPlanManager implements QueryPlanManager {
|
||||||
|
|
||||||
|
private static final System.Logger log = CoreLog.internal;
|
||||||
private static final Object dummy = new Object();
|
private static final Object dummy = new Object();
|
||||||
|
|
||||||
private final ConcurrentHashMap<CQueryBindCapture, Object> plans = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<CQueryBindCapture, Object> plans = new ConcurrentHashMap<>();
|
||||||
@@ -24,14 +29,25 @@ public final class CQueryPlanManager implements QueryPlanManager {
|
|||||||
private final QueryPlanLogger planLogger;
|
private final QueryPlanLogger planLogger;
|
||||||
private final TimedMetric timeCollection;
|
private final TimedMetric timeCollection;
|
||||||
private final TimedMetric timeBindCapture;
|
private final TimedMetric timeBindCapture;
|
||||||
|
private final DefaultServer server;
|
||||||
|
private final QueryPlanListener listener;
|
||||||
|
private final int maxCount;
|
||||||
|
private final long maxTimeMillis;
|
||||||
private long defaultThreshold;
|
private long defaultThreshold;
|
||||||
|
|
||||||
public CQueryPlanManager(TransactionManager transactionManager, long defaultThreshold, QueryPlanLogger planLogger, ExtraMetrics extraMetrics) {
|
public CQueryPlanManager(DefaultServer server, TransactionManager transactionManager, long defaultThreshold, QueryPlanLogger planLogger, ExtraMetrics extraMetrics) {
|
||||||
|
this.server = server;
|
||||||
this.transactionManager = transactionManager;
|
this.transactionManager = transactionManager;
|
||||||
this.defaultThreshold = defaultThreshold;
|
this.defaultThreshold = defaultThreshold;
|
||||||
this.planLogger = planLogger;
|
this.planLogger = planLogger;
|
||||||
this.timeCollection = extraMetrics.planCollect();
|
this.timeCollection = extraMetrics.planCollect();
|
||||||
this.timeBindCapture = extraMetrics.bindCapture();
|
this.timeBindCapture = extraMetrics.bindCapture();
|
||||||
|
|
||||||
|
final var config = server.config();
|
||||||
|
this.maxCount = config.getQueryPlanCaptureMaxCount();
|
||||||
|
this.maxTimeMillis = config.getQueryPlanCaptureMaxTimeMillis();
|
||||||
|
final var planListener = config.getQueryPlanListener();
|
||||||
|
this.listener = (planListener != null) ? planListener : DefaultQueryPlanListener.INSTANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -49,15 +65,28 @@ public final class CQueryPlanManager implements QueryPlanManager {
|
|||||||
timeBindCapture.addSinceNanos(startNanos);
|
timeBindCapture.addSinceNanos(startNanos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startPlanCapture() {
|
||||||
|
final var config = server.config();
|
||||||
|
if (config.isQueryPlanCapture()) {
|
||||||
|
long secs = config.getQueryPlanCapturePeriodSecs();
|
||||||
|
if (secs > 10) {
|
||||||
|
log.log(INFO, "capture query plan enabled, every {0}secs", secs);
|
||||||
|
server.backgroundExecutor().scheduleWithFixedDelay(this::collectQueryPlans, secs, secs, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectQueryPlans() {
|
||||||
|
List<MetaQueryPlan> plans = collect(new QueryPlanRequest(maxCount, maxTimeMillis));
|
||||||
|
listener.process(new QueryPlanCapture(server, plans));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MetaQueryPlan> collect(QueryPlanRequest request) {
|
public List<MetaQueryPlan> collect(QueryPlanRequest request) {
|
||||||
if (plans.isEmpty()) {
|
if (plans.isEmpty()) {
|
||||||
return emptyList();
|
return emptyList();
|
||||||
}
|
}
|
||||||
return collectPlans(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<MetaQueryPlan> collectPlans(QueryPlanRequest request) {
|
|
||||||
try (Connection connection = transactionManager.queryPlanConnection()) {
|
try (Connection connection = transactionManager.queryPlanConnection()) {
|
||||||
CQueryPlanRequest req = new CQueryPlanRequest(connection, request, plans.keySet().iterator());
|
CQueryPlanRequest req = new CQueryPlanRequest(connection, request, plans.keySet().iterator());
|
||||||
while (req.hasNext()) {
|
while (req.hasNext()) {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package io.ebeaninternal.server.core;
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
import io.avaje.applog.AppLog;
|
import io.avaje.applog.AppLog;
|
||||||
import io.ebean.config.QueryPlanCapture;
|
import io.ebean.config.QueryPlanCapture;
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:14.2.0</tile>
|
<tile>io.ebean.tile:enhancement:14.1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -100,7 +100,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:14.2.0</tile>
|
<tile>io.ebean.tile:enhancement:14.1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
|
|||||||
* Eagerly fetch this association fetching all the properties.
|
* Eagerly fetch this association fetching all the properties.
|
||||||
*/
|
*/
|
||||||
public final R fetch() {
|
public final R fetch() {
|
||||||
((QueryBean) _root).query().fetch(_name);
|
((TQRootBean) _root).query().fetch(_name);
|
||||||
return _root;
|
return _root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
|
|||||||
* Eagerly fetch this association using a "query join".
|
* Eagerly fetch this association using a "query join".
|
||||||
*/
|
*/
|
||||||
public final R fetchQuery() {
|
public final R fetchQuery() {
|
||||||
((QueryBean) _root).query().fetchQuery(_name);
|
((TQRootBean) _root).query().fetchQuery(_name);
|
||||||
return _root;
|
return _root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
|
|||||||
* Cache misses are populated via fetchQuery().
|
* Cache misses are populated via fetchQuery().
|
||||||
*/
|
*/
|
||||||
public final R fetchCache() {
|
public final R fetchCache() {
|
||||||
((QueryBean) _root).query().fetchCache(_name);
|
((TQRootBean) _root).query().fetchCache(_name);
|
||||||
return _root;
|
return _root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
|
|||||||
* Use lazy loading for fetching this association.
|
* Use lazy loading for fetching this association.
|
||||||
*/
|
*/
|
||||||
public final R fetchLazy() {
|
public final R fetchLazy() {
|
||||||
((QueryBean) _root).query().fetchLazy(_name);
|
((TQRootBean) _root).query().fetchLazy(_name);
|
||||||
return _root;
|
return _root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
|
|||||||
* Eagerly fetch this association with the properties specified.
|
* Eagerly fetch this association with the properties specified.
|
||||||
*/
|
*/
|
||||||
public final R fetch(String properties) {
|
public final R fetch(String properties) {
|
||||||
((QueryBean) _root).query().fetch(_name, properties);
|
((TQRootBean) _root).query().fetch(_name, properties);
|
||||||
return _root;
|
return _root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
|
|||||||
* Eagerly fetch this association using a "query join" with the properties specified.
|
* Eagerly fetch this association using a "query join" with the properties specified.
|
||||||
*/
|
*/
|
||||||
public final R fetchQuery(String properties) {
|
public final R fetchQuery(String properties) {
|
||||||
((QueryBean) _root).query().fetchQuery(_name, properties);
|
((TQRootBean) _root).query().fetchQuery(_name, properties);
|
||||||
return _root;
|
return _root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
|
|||||||
* Cache misses are populated via fetchQuery().
|
* Cache misses are populated via fetchQuery().
|
||||||
*/
|
*/
|
||||||
public final R fetchCache(String properties) {
|
public final R fetchCache(String properties) {
|
||||||
((QueryBean) _root).query().fetchCache(_name, properties);
|
((TQRootBean) _root).query().fetchCache(_name, properties);
|
||||||
return _root;
|
return _root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SpiQueryFetch spiQuery() {
|
private SpiQueryFetch spiQuery() {
|
||||||
return (SpiQueryFetch) ((QueryBean) _root).query();
|
return (SpiQueryFetch) ((TQRootBean) _root).query();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> properties(TQProperty<?, ?>... props) {
|
private Set<String> properties(TQProperty<?, ?>... props) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class TQProperty<R, T> implements Query.Property<T> {
|
|||||||
* Internal method to return the underlying expression list.
|
* Internal method to return the underlying expression list.
|
||||||
*/
|
*/
|
||||||
protected final ExpressionList<?> expr() {
|
protected final ExpressionList<?> expr() {
|
||||||
return ((QueryBean<?, ?>) _root).peekExprList();
|
return ((TQRootBean<?, ?>) _root).peekExprList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+8
-8
@@ -57,7 +57,7 @@ import java.util.stream.Stream;
|
|||||||
* @param <R> the specific root query bean type (e.g. QCustomer)
|
* @param <R> the specific root query bean type (e.g. QCustomer)
|
||||||
*/
|
*/
|
||||||
@NonNullApi
|
@NonNullApi
|
||||||
public abstract class QueryBean<T, R> implements IQueryBean<T, R> {
|
public abstract class TQRootBean<T, R> implements IQueryBean<T, R> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The underlying query.
|
* The underlying query.
|
||||||
@@ -88,21 +88,21 @@ public abstract class QueryBean<T, R> implements IQueryBean<T, R> {
|
|||||||
/**
|
/**
|
||||||
* Construct using the type of bean to query on and the default database.
|
* Construct using the type of bean to query on and the default database.
|
||||||
*/
|
*/
|
||||||
public QueryBean(Class<T> beanType) {
|
public TQRootBean(Class<T> beanType) {
|
||||||
this(beanType, DB.getDefault());
|
this(beanType, DB.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct using the type of bean to query on and a given database.
|
* Construct using the type of bean to query on and a given database.
|
||||||
*/
|
*/
|
||||||
public QueryBean(Class<T> beanType, Database database) {
|
public TQRootBean(Class<T> beanType, Database database) {
|
||||||
this(database.find(beanType));
|
this(database.find(beanType));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct with a transaction.
|
* Construct with a transaction.
|
||||||
*/
|
*/
|
||||||
protected QueryBean(Class<T> beanType, Transaction transaction) {
|
protected TQRootBean(Class<T> beanType, Transaction transaction) {
|
||||||
this(beanType);
|
this(beanType);
|
||||||
query.usingTransaction(transaction);
|
query.usingTransaction(transaction);
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ public abstract class QueryBean<T, R> implements IQueryBean<T, R> {
|
|||||||
/**
|
/**
|
||||||
* Construct with a database and transaction.
|
* Construct with a database and transaction.
|
||||||
*/
|
*/
|
||||||
protected QueryBean(Class<T> beanType, Database database, Transaction transaction) {
|
protected TQRootBean(Class<T> beanType, Database database, Transaction transaction) {
|
||||||
this(beanType, database);
|
this(beanType, database);
|
||||||
query.usingTransaction(transaction);
|
query.usingTransaction(transaction);
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ public abstract class QueryBean<T, R> implements IQueryBean<T, R> {
|
|||||||
* Construct using a query.
|
* Construct using a query.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public QueryBean(Query<T> query) {
|
public TQRootBean(Query<T> query) {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.root = (R) this;
|
this.root = (R) this;
|
||||||
}
|
}
|
||||||
@@ -129,13 +129,13 @@ public abstract class QueryBean<T, R> implements IQueryBean<T, R> {
|
|||||||
* values for select() and fetch().
|
* values for select() and fetch().
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public QueryBean(boolean aliasDummy) {
|
public TQRootBean(boolean aliasDummy) {
|
||||||
this.query = null;
|
this.query = null;
|
||||||
this.root = (R) this;
|
this.root = (R) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Construct for FilterMany */
|
/** Construct for FilterMany */
|
||||||
protected QueryBean(ExpressionList<T> filter) {
|
protected TQRootBean(ExpressionList<T> filter) {
|
||||||
this.query = null;
|
this.query = null;
|
||||||
this.root = null;
|
this.root = null;
|
||||||
this.whereStack = new ArrayStack<>();
|
this.whereStack = new ArrayStack<>();
|
||||||
+1
-1
@@ -72,7 +72,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:14.2.0</tile>
|
<tile>io.ebean.tile:enhancement:14.1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -99,7 +99,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:14.2.0</tile>
|
<tile>io.ebean.tile:enhancement:14.1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
+1
-1
@@ -309,7 +309,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:14.2.0</tile>
|
<tile>io.ebean.tile:enhancement:14.1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -199,11 +199,8 @@ public class TestCustomerFinder extends BaseTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// obtains db query plans ...
|
// obtains db query plans ...
|
||||||
QueryPlanRequest request = new QueryPlanRequest();
|
// collect max 10 plans, after 10 secs don't collect any more plans
|
||||||
// collect max 1000 plans (use something more like 10)
|
var request = new QueryPlanRequest(10, 10_000);
|
||||||
request.maxCount(1_000);
|
|
||||||
// don't collect any more plans if used 10 secs
|
|
||||||
request.maxTimeMillis(10_000);
|
|
||||||
List<MetaQueryPlan> plans0 = server().metaInfo().queryPlanCollectNow(request);
|
List<MetaQueryPlan> plans0 = server().metaInfo().queryPlanCollectNow(request);
|
||||||
assertThat(plans0).isNotEmpty();
|
assertThat(plans0).isNotEmpty();
|
||||||
|
|
||||||
@@ -214,7 +211,7 @@ public class TestCustomerFinder extends BaseTestCase {
|
|||||||
System.out.println(plan);
|
System.out.println(plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
//DB.getBackgroundExecutor().scheduleWithFixedDelay(...)
|
// DB.backgroundExecutor().scheduleWithFixedDelay(...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+1
-1
@@ -337,7 +337,7 @@ class SimpleQueryBeanWriter {
|
|||||||
writer.append(" */").eol();
|
writer.append(" */").eol();
|
||||||
writer.append(Constants.AT_GENERATED).eol();
|
writer.append(Constants.AT_GENERATED).eol();
|
||||||
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
|
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
|
||||||
writer.append("class Q%s : io.ebean.typequery.QueryBean<%s, Q%s> {", shortName, beanFullName, shortName).eol();
|
writer.append("class Q%s : io.ebean.typequery.TQRootBean<%s, Q%s> {", shortName, beanFullName, shortName).eol();
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.eol();
|
writer.eol();
|
||||||
|
|||||||
+1
-1
@@ -225,7 +225,7 @@ class SimpleQueryBeanWriter {
|
|||||||
writer.append("public final class Q%s {", shortName).eol();
|
writer.append("public final class Q%s {", shortName).eol();
|
||||||
} else {
|
} else {
|
||||||
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
|
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
|
||||||
writer.append("public final class Q%s extends io.ebean.typequery.QueryBean<%s,Q%s> {", shortName, beanFullName, shortName).eol();
|
writer.append("public final class Q%s extends io.ebean.typequery.TQRootBean<%s,Q%s> {", shortName, beanFullName, shortName).eol();
|
||||||
}
|
}
|
||||||
writer.eol();
|
writer.eol();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<artifactId>test-java16</artifactId>
|
<artifactId>test-java16</artifactId>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.release>17</maven.compiler.release>
|
<java.release>16</java.release>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:14.2.0</tile>
|
<tile>io.ebean.tile:enhancement:14.1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
Reference in New Issue
Block a user