mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Imporved @Where support, especially for Many-to-many tables
This commit is contained in:
@@ -119,7 +119,7 @@ public class LoadManyRequest extends LoadRequest {
|
||||
if (extraWhere != null) {
|
||||
// replace special ${ta} placeholder with the base table alias
|
||||
// which is always t0 and add the extra where clause
|
||||
query.where().raw(extraWhere.replace("${ta}", "t0"));
|
||||
query.where().raw(extraWhere.replace("${ta}", "t0").replace("${mta}", "int_"));
|
||||
}
|
||||
|
||||
query.setLazyLoadForParents(many);
|
||||
|
||||
@@ -2009,6 +2009,13 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return owner.getBeanDescriptor(otherType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if the table is managed (i.e. an existing m2m relation).
|
||||
*/
|
||||
public boolean isTableManaged(String tableName) {
|
||||
return owner.isTableManaged(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order column property.
|
||||
*/
|
||||
|
||||
@@ -445,6 +445,12 @@ public class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTypeMana
|
||||
return tableToDescMap.get(tableName.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTableManaged(String tableName) {
|
||||
return tableToDescMap.get(tableName.toLowerCase()) != null
|
||||
|| tableToViewDescMap.get(tableName.toLowerCase()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate entity beans based on views via their dependent tables.
|
||||
*/
|
||||
|
||||
@@ -76,4 +76,10 @@ public interface BeanDescriptorMap {
|
||||
* Return true if Jackson core is present on the classpath.
|
||||
*/
|
||||
boolean isJacksonCorePresent();
|
||||
|
||||
/**
|
||||
* Returns true, if the given table (or view) is managed by ebean
|
||||
* (= an entity exists)
|
||||
*/
|
||||
boolean isTableManaged(String tableName);
|
||||
}
|
||||
|
||||
@@ -439,6 +439,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
@Override
|
||||
public String getAssocIsEmpty(SpiExpressionRequest request, String path) {
|
||||
boolean softDelete = targetDescriptor.isSoftDelete();
|
||||
boolean needsX2Table = softDelete || getExtraWhere() != null;
|
||||
StringBuilder sb = new StringBuilder(50);
|
||||
SpiQuery<?> query = request.getQueryRequest().getQuery();
|
||||
if (hasJoinTable()) {
|
||||
@@ -446,7 +447,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
} else {
|
||||
sb.append(targetDescriptor.getBaseTable(query.getTemporalMode()));
|
||||
}
|
||||
if (softDelete && hasJoinTable()) {
|
||||
if (needsX2Table && hasJoinTable()) {
|
||||
sb.append(" x join ");
|
||||
sb.append(targetDescriptor.getBaseTable(query.getTemporalMode()));
|
||||
sb.append(" x2 on ");
|
||||
@@ -461,6 +462,16 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
}
|
||||
exportedProperties[i].appendWhere(sb, "x.", path);
|
||||
}
|
||||
if (getExtraWhere() != null) {
|
||||
sb.append(" and ");
|
||||
if (hasJoinTable()) {
|
||||
sb.append(getExtraWhere().replace("${ta}", "x2").replace("${mta}", "x"));
|
||||
} else {
|
||||
sb.append(getExtraWhere().replace("${ta}", "x"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (softDelete) {
|
||||
String alias = hasJoinTable() ? "x2" : "x";
|
||||
sb.append(" and ").append(targetDescriptor.getSoftDeletePredicate(alias));
|
||||
@@ -1061,4 +1072,16 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
public void bindElementValue(SqlUpdate insert, Object value) {
|
||||
targetDescriptor.bindElementValue(insert, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if we must create a m2m join table.
|
||||
*/
|
||||
public boolean createJoinTable() {
|
||||
if (hasJoinTable() && getMappedBy() == null) {
|
||||
// only create on other 'owning' side
|
||||
return !descriptor.isTableManaged(intersectionJoin.getTable());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public interface DbSqlContext {
|
||||
/**
|
||||
* Add a join to the sql query.
|
||||
*/
|
||||
void addJoin(String type, String table, TableJoinColumn[] cols, String a1, String a2);
|
||||
void addJoin(String type, String table, TableJoinColumn[] cols, String a1, String a2, String extraWhere);
|
||||
|
||||
/**
|
||||
* Push the current table alias onto the stack.
|
||||
|
||||
@@ -34,6 +34,8 @@ public final class TableJoin {
|
||||
private final int queryHash;
|
||||
|
||||
private final PropertyForeignKey foreignKey;
|
||||
|
||||
private final String extraWhere;
|
||||
|
||||
public TableJoin(DeployTableJoin deploy) {
|
||||
this(deploy, null);
|
||||
@@ -44,6 +46,7 @@ public final class TableJoin {
|
||||
*/
|
||||
public TableJoin(DeployTableJoin deploy, PropertyForeignKey foreignKey) {
|
||||
this.foreignKey = foreignKey;
|
||||
this.extraWhere = deploy.getExtraWhere();
|
||||
this.table = InternString.intern(deploy.getTable());
|
||||
this.type = deploy.getType();
|
||||
this.inheritInfo = deploy.getInheritInfo();
|
||||
@@ -57,6 +60,7 @@ public final class TableJoin {
|
||||
|
||||
private TableJoin(TableJoin source, String overrideColumn) {
|
||||
this.foreignKey = null;
|
||||
this.extraWhere = source.extraWhere;
|
||||
this.table = source.table;
|
||||
this.type = source.type;
|
||||
this.inheritInfo = source.inheritInfo;
|
||||
@@ -146,7 +150,7 @@ public final class TableJoin {
|
||||
|
||||
public SqlJoinType addJoin(SqlJoinType joinType, String a1, String a2, DbSqlContext ctx) {
|
||||
String joinLiteral = joinType.getLiteral(type);
|
||||
ctx.addJoin(joinLiteral, table, columns(), a1, a2);
|
||||
ctx.addJoin(joinLiteral, table, columns(), a1, a2, extraWhere);
|
||||
return joinType.autoToOuter(type);
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -86,6 +86,7 @@ public abstract class DeployBeanPropertyAssoc<T> extends DeployBeanProperty {
|
||||
* collection.
|
||||
*/
|
||||
public void setExtraWhere(String extraWhere) {
|
||||
this.tableJoin.setExtraWhere(extraWhere);
|
||||
this.extraWhere = extraWhere;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ public class DeployTableJoin {
|
||||
private ArrayList<DeployTableJoinColumn> columns = new ArrayList<>(4);
|
||||
|
||||
private InheritInfo inheritInfo;
|
||||
|
||||
private String extraWhere;
|
||||
|
||||
/**
|
||||
* Create a DeployTableJoin.
|
||||
@@ -137,6 +139,18 @@ public class DeployTableJoin {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the clause of an extra @Where annotation.
|
||||
* @return
|
||||
*/
|
||||
public String getExtraWhere() {
|
||||
return extraWhere;
|
||||
}
|
||||
|
||||
public void setExtraWhere(String extraWhere) {
|
||||
this.extraWhere = extraWhere;
|
||||
}
|
||||
|
||||
public DeployTableJoin createInverse(String tableName) {
|
||||
|
||||
DeployTableJoin inverse = new DeployTableJoin();
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ class AnnotationAssocManys extends AnnotationAssoc {
|
||||
|
||||
Where where = prop.getMetaAnnotationWhere(platform);
|
||||
if (where != null) {
|
||||
prop.setExtraWhere(where.clause());
|
||||
prop.setExtraWhere(processFormula(where.clause()));
|
||||
}
|
||||
|
||||
FetchPreference fetchPreference = get(prop, FetchPreference.class);
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ public class AnnotationAssocOnes extends AnnotationAssoc {
|
||||
Where where = prop.getMetaAnnotationWhere(platform);
|
||||
if (where != null) {
|
||||
// not expecting this to be used on assoc one properties
|
||||
prop.setExtraWhere(where.clause());
|
||||
prop.setExtraWhere(processFormula(where.clause()));
|
||||
}
|
||||
|
||||
PrimaryKeyJoinColumn primaryKeyJoin = get(prop, PrimaryKeyJoinColumn.class);
|
||||
|
||||
@@ -153,7 +153,7 @@ public class AnnotationFields extends AnnotationParser {
|
||||
|
||||
Formula formula = prop.getMetaAnnotationFormula(platform);
|
||||
if (formula != null) {
|
||||
prop.setSqlFormula(formula.select(), formula.join());
|
||||
prop.setSqlFormula(processFormula(formula.select()), processFormula(formula.join()));
|
||||
}
|
||||
|
||||
initWhoProperties(prop);
|
||||
@@ -334,7 +334,7 @@ public class AnnotationFields extends AnnotationParser {
|
||||
}
|
||||
Formula formula = prop.getMetaAnnotationFormula(platform);
|
||||
if (formula != null) {
|
||||
prop.setSqlFormula(formula.select(), formula.join());
|
||||
prop.setSqlFormula(processFormula(formula.select()), processFormula(formula.join()));
|
||||
}
|
||||
|
||||
final Aggregation aggregation = prop.getMetaAnnotation(Aggregation.class);
|
||||
|
||||
@@ -129,4 +129,11 @@ public abstract class AnnotationParser extends AnnotationBase {
|
||||
}
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process any formula from @Formula or @Where.
|
||||
*/
|
||||
protected String processFormula(String source) {
|
||||
return source == null ? null : source.replace("${dbTableName}", descriptor.getBaseTable());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ class DefaultDbSqlContext implements DbSqlContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addJoin(String type, String table, TableJoinColumn[] cols, String a1, String a2) {
|
||||
public void addJoin(String type, String table, TableJoinColumn[] cols, String a1, String a2, String extraWhere) {
|
||||
|
||||
if (tableJoins == null) {
|
||||
tableJoins = new HashSet<>();
|
||||
@@ -164,6 +164,14 @@ class DefaultDbSqlContext implements DbSqlContext {
|
||||
if (addAsOfOnClause) {
|
||||
sb.append(" and ").append(historySupport.getAsOfPredicate(a2));
|
||||
}
|
||||
|
||||
if (extraWhere != null && !extraWhere.isEmpty()) {
|
||||
sb.append(" and ");
|
||||
// we will also need a many-table alias here
|
||||
sb.append(extraWhere.replace(tableAliasPlaceHolder, a2).replace("${mta}", a1));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void appendTable(String table, String draftTable) {
|
||||
|
||||
@@ -47,16 +47,6 @@ final class SqlTreeNodeManyRoot extends SqlTreeNodeBean {
|
||||
ctx.popTableAlias();
|
||||
}
|
||||
|
||||
/**
|
||||
* append extraWhere to the join.
|
||||
*/
|
||||
@Override
|
||||
protected SqlJoinType appendFromAsJoin(DbSqlContext ctx, SqlJoinType joinType) {
|
||||
SqlJoinType join = super.appendFromAsJoin(ctx, joinType);
|
||||
super.appendExtraWhere(ctx);
|
||||
return join;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendExtraWhere(DbSqlContext ctx) {
|
||||
// extraWhere is already appended to the tableJoin
|
||||
|
||||
Reference in New Issue
Block a user