mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1427 - QueryCache should be cleared, if one of a dependent bean is updated
Initial work, does not include propagation across cluster.
This commit is contained in:
@@ -38,6 +38,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An object that represents a SqlSelect statement.
|
||||
@@ -811,4 +812,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
|
||||
PreparedStatement getPstmt() {
|
||||
return pstmt;
|
||||
}
|
||||
|
||||
public Set<String> getDependentTables() {
|
||||
return queryPlan.getDependentTables();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import org.slf4j.LoggerFactory;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -111,6 +113,15 @@ public class CQueryEngine {
|
||||
if (request.isLogSummary()) {
|
||||
request.getTransaction().logSummary(rcQuery.getSummary());
|
||||
}
|
||||
if (request.isQueryCachePut() && !list.isEmpty()) {
|
||||
request.addDependentTables(rcQuery.getDependentTables());
|
||||
|
||||
list = Collections.unmodifiableList(list);
|
||||
request.putToQueryCache(list);
|
||||
if (Boolean.FALSE.equals(request.getQuery().isReadOnly())) {
|
||||
list = new ArrayList<>(list);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
|
||||
} catch (SQLException e) {
|
||||
@@ -173,6 +184,11 @@ public class CQueryEngine {
|
||||
request.getTransaction().end();
|
||||
}
|
||||
|
||||
if (request.isQueryCachePut()) {
|
||||
request.addDependentTables(rcQuery.getDependentTables());
|
||||
request.putToQueryCache(count);
|
||||
}
|
||||
|
||||
return count;
|
||||
|
||||
} catch (SQLException e) {
|
||||
@@ -385,6 +401,9 @@ public class CQueryEngine {
|
||||
}
|
||||
|
||||
request.executeSecondaryQueries(false);
|
||||
if (request.isQueryCachePut()) {
|
||||
request.addDependentTables(cquery.getDependentTables());
|
||||
}
|
||||
|
||||
return beanCollection;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Base compiled query request for single attribute queries.
|
||||
@@ -188,4 +189,8 @@ class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent {
|
||||
.profileStream()
|
||||
.addQueryEvent(query.profileEventId(), profileOffset, desc.getProfileId(), rowCount, query.getProfileId());
|
||||
}
|
||||
|
||||
Set<String> getDependentTables() {
|
||||
return queryPlan.getDependentTables();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents a query for a given SQL statement.
|
||||
@@ -88,6 +90,8 @@ public class CQueryPlan {
|
||||
*/
|
||||
private volatile String auditQueryHash;
|
||||
|
||||
private final Set<String> dependentTables;
|
||||
|
||||
/**
|
||||
* Create a query plan based on a OrmQueryRequest.
|
||||
*/
|
||||
@@ -110,6 +114,7 @@ public class CQueryPlan {
|
||||
this.logWhereSql = logWhereSql;
|
||||
this.encryptedProps = sqlTree.getEncryptedProps();
|
||||
this.stats = new CQueryPlanStats(this, server.isCollectQueryOrigins());
|
||||
this.dependentTables = sqlTree.dependentTables();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,6 +139,7 @@ public class CQueryPlan {
|
||||
this.logWhereSql = logWhereSql;
|
||||
this.encryptedProps = sqlTree.getEncryptedProps();
|
||||
this.stats = new CQueryPlanStats(this, server.isCollectQueryOrigins());
|
||||
this.dependentTables = (rawSql) ? Collections.emptySet() : sqlTree.dependentTables();
|
||||
}
|
||||
|
||||
private String location() {
|
||||
@@ -154,6 +160,10 @@ public class CQueryPlan {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
public Set<String> getDependentTables() {
|
||||
return dependentTables;
|
||||
}
|
||||
|
||||
public ProfileLocation getProfileLocation() {
|
||||
return profileLocation;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Executes the select row count query.
|
||||
@@ -154,4 +155,8 @@ class CQueryRowCount implements SpiProfileTransactionEvent {
|
||||
.profileStream()
|
||||
.addQueryEvent(query.profileEventId(), profileOffset, desc.getProfileId(), rowCount, query.getProfileId());
|
||||
}
|
||||
|
||||
Set<String> getDependentTables() {
|
||||
return queryPlan.getDependentTables();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,41 +88,20 @@ public class DefaultOrmQueryEngine implements OrmQueryEngine {
|
||||
public <T> int findCount(OrmQueryRequest<T> request) {
|
||||
|
||||
flushJdbcBatchOnQuery(request);
|
||||
int result = queryEngine.findCount(request);
|
||||
if (request.getQuery().getUseQueryCache().isPut()) {
|
||||
request.putToQueryCache(result);
|
||||
}
|
||||
return result;
|
||||
return queryEngine.findCount(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> List<A> findIds(OrmQueryRequest<?> request) {
|
||||
|
||||
flushJdbcBatchOnQuery(request);
|
||||
List<A> result = queryEngine.findIds(request);
|
||||
if (request.getQuery().getUseQueryCache().isPut()) {
|
||||
result = Collections.unmodifiableList(result);
|
||||
request.putToQueryCache(result);
|
||||
if (Boolean.FALSE.equals(request.getQuery().isReadOnly())) {
|
||||
result = new ArrayList<>(result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return queryEngine.findIds(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> List<A> findSingleAttributeList(OrmQueryRequest<?> request) {
|
||||
flushJdbcBatchOnQuery(request);
|
||||
List<A> result = queryEngine.findSingleAttributeList(request);
|
||||
if (!result.isEmpty() && request.getQuery().getUseQueryCache().isPut()) {
|
||||
// load the query result into the query cache
|
||||
result = Collections.unmodifiableList(result);
|
||||
request.putToQueryCache(result);
|
||||
if (Boolean.FALSE.equals(request.getQuery().isReadOnly())) {
|
||||
result = new ArrayList<>(result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return queryEngine.findSingleAttributeList(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.ebeaninternal.server.query;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -163,4 +164,13 @@ class SqlTree {
|
||||
boolean isSingleProperty() {
|
||||
return rootNode.isSingleProperty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the tables that are joined in this query.
|
||||
*/
|
||||
Set<String> dependentTables() {
|
||||
Set<String> tables = new LinkedHashSet<>();
|
||||
rootNode.dependentTables(tables);
|
||||
return tables;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import io.ebeaninternal.server.type.ScalarType;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
interface SqlTreeNode {
|
||||
|
||||
@@ -87,4 +88,9 @@ interface SqlTreeNode {
|
||||
* Return true if the query is known to only have a single property selected.
|
||||
*/
|
||||
boolean isSingleProperty();
|
||||
|
||||
/**
|
||||
* Add dependent tables to the given set.
|
||||
*/
|
||||
void dependentTables(Set<String> tables);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.sql.Timestamp;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Normal bean included in the query.
|
||||
@@ -578,6 +579,14 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dependentTables(Set<String> tables) {
|
||||
tables.add(nodeBeanProp.target().getBaseTable(temporalMode));
|
||||
for (SqlTreeNode child : children) {
|
||||
child.dependentTables(tables);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Join to base table for this node. This includes a join to the intersection
|
||||
* table if this is a ManyToMany node.
|
||||
|
||||
@@ -11,6 +11,7 @@ import io.ebeaninternal.server.type.ScalarType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The purpose is to add an extra join to the query.
|
||||
@@ -100,6 +101,16 @@ class SqlTreeNodeExtraJoin implements SqlTreeNode {
|
||||
children.add(child);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dependentTables(Set<String> tables) {
|
||||
tables.add(assocBeanProperty.target().getBaseTable(SpiQuery.TemporalMode.CURRENT));
|
||||
if (children != null) {
|
||||
for (SqlTreeNode child : children) {
|
||||
child.dependentTables(tables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendFrom(DbSqlContext ctx, SqlJoinType joinType) {
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
final class SqlTreeNodeManyRoot extends SqlTreeNodeBean {
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.ebeaninternal.server.deploy.TableJoin;
|
||||
import io.ebeaninternal.server.type.ScalarType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Join to Many (or child of a many) to support where clause predicates on many properties.
|
||||
@@ -109,6 +110,11 @@ class SqlTreeNodeManyWhereJoin implements SqlTreeNode {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dependentTables(Set<String> tables) {
|
||||
tables.add(nodeBeanProp.target().getBaseTable(SpiQuery.TemporalMode.CURRENT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildRawSqlSelectChain(List<String> selectChain) {
|
||||
// nothing to add
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||
import io.ebeaninternal.server.deploy.TableJoin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents the root node of the Sql Tree.
|
||||
@@ -77,4 +78,10 @@ final class SqlTreeNodeRoot extends SqlTreeNodeBean {
|
||||
return joinType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dependentTables(Set<String> tables) {
|
||||
for (SqlTreeNode child : children) {
|
||||
child.dependentTables(tables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user