diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionFactory.java index 2cb77ece6..6d76fa901 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionFactory.java @@ -726,7 +726,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory { */ @Override public Junction conjunction(Query query) { - return new JunctionExpression<>(Junction.Type.AND, query, query.where()); + return new JunctionExpression<>(Junction.Type.AND, query, this, query.where()); } /** @@ -734,7 +734,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory { */ @Override public Junction disjunction(Query query) { - return new JunctionExpression<>(Junction.Type.OR, query, query.where()); + return new JunctionExpression<>(Junction.Type.OR, query, this, query.where()); } /** @@ -742,7 +742,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory { */ @Override public Junction conjunction(Query query, ExpressionList parent) { - return new JunctionExpression<>(Junction.Type.AND, query, parent); + return new JunctionExpression<>(Junction.Type.AND, query, this, parent); } /** @@ -750,14 +750,14 @@ public class DefaultExpressionFactory implements SpiExpressionFactory { */ @Override public Junction disjunction(Query query, ExpressionList parent) { - return new JunctionExpression<>(Junction.Type.OR, query, parent); + return new JunctionExpression<>(Junction.Type.OR, query, this, parent); } /** * Return a list of expressions that are wrapped by NOT. */ public Junction junction(Junction.Type type, Query query) { - return new JunctionExpression<>(type, query, query.where()); + return new JunctionExpression<>(type, query, this, query.where()); } /** @@ -765,6 +765,6 @@ public class DefaultExpressionFactory implements SpiExpressionFactory { */ @Override public Junction junction(Junction.Type type, Query query, ExpressionList parent) { - return new JunctionExpression<>(type, query, parent); + return new JunctionExpression<>(type, query, this, parent); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java index f3c25cb36..5d50ca1dd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java @@ -40,12 +40,8 @@ public class DefaultExpressionList implements SpiExpressionList { /** * Construct for Text root expression list - this handles implicit Bool Should, Must etc. */ - public DefaultExpressionList(Query query) { - this(query, query.getExpressionFactory(), null, new ArrayList<>(), true); - } - - public DefaultExpressionList(Query query, ExpressionList parentExprList) { - this(query, query.getExpressionFactory(), parentExprList, new ArrayList<>()); + public DefaultExpressionList(Query query, boolean textRoot) { + this(query, query.getExpressionFactory(), null, new ArrayList<>(), textRoot); } DefaultExpressionList(Query query, ExpressionFactory expr, ExpressionList parentExprList, List list) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index 77e1dc879..2861237a2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -24,9 +24,9 @@ final class JunctionExpression implements SpiJunction, SpiExpression, Expr DefaultExpressionList exprList; Junction.Type type; - JunctionExpression(Junction.Type type, Query query, ExpressionList parent) { + JunctionExpression(Junction.Type type, Query query, ExpressionFactory expr, ExpressionList parent) { this.type = type; - this.exprList = new DefaultExpressionList<>(query, parent); + this.exprList = new DefaultExpressionList<>(query, expr, parent, new ArrayList<>()); } /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index 3f34efa21..a70c6547c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -1895,7 +1895,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { public final ExpressionList text() { if (textExpressions == null) { useDocStore = true; - textExpressions = new DefaultExpressionList<>(this); + textExpressions = new DefaultExpressionList<>(this, true); } return textExpressions; } @@ -1903,7 +1903,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { @Override public final ExpressionList where() { if (whereExpressions == null) { - whereExpressions = new DefaultExpressionList<>(this, null); + whereExpressions = new DefaultExpressionList<>(this, false); } return whereExpressions; } @@ -1924,7 +1924,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { @Override public final ExpressionList having() { if (havingExpressions == null) { - havingExpressions = new DefaultExpressionList<>(this, null); + havingExpressions = new DefaultExpressionList<>(this, false); } return havingExpressions; } diff --git a/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java b/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java index 1bb177edb..275857060 100644 --- a/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java +++ b/ebean-querybean/src/main/java/io/ebean/typequery/QueryBean.java @@ -121,7 +121,7 @@ public abstract class QueryBean> implements IQueryB /** Construct for FilterMany */ protected QueryBean(ExpressionList filter) { this.query = null; - this.root = null; + this.root = (R) this; this.whereStack = new ArrayStack<>(); whereStack.push(filter); } diff --git a/ebean-querybean/src/test/java/org/querytest/QCustomerTest.java b/ebean-querybean/src/test/java/org/querytest/QCustomerTest.java index 94bc12098..cc17a4365 100644 --- a/ebean-querybean/src/test/java/org/querytest/QCustomerTest.java +++ b/ebean-querybean/src/test/java/org/querytest/QCustomerTest.java @@ -377,6 +377,20 @@ public class QCustomerTest { assertThat(q.getGeneratedSql()).contains(" from be_customer t0 left join be_contact t1 on t1.customer_id = t0.id where (t1.id is null or (t1.first_name like ? and t1.first_name like ? escape'|')) order by t0.id"); } + @Test + void filterManyOr() { + var q = new QCustomer() + .contacts.filterMany(c -> + c.or() + .firstName.startsWith("R") + .lastName.startsWith("R") + .endOr()) + .query(); + + q.findList(); + assertThat(q.getGeneratedSql()).contains(" from be_customer t0 left join be_contact t1 on t1.customer_id = t0.id where (t1.id is null or ((t1.first_name like ? escape'|' or t1.last_name like ? escape'|'))) order by t0.id"); + } + @Test public void testIdIn() {