From 2e1b52d7d402fbbb44c62e3e7764db1ecb2c0944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kal=C3=A1b?= Date: Thu, 18 Jan 2024 11:32:34 +0100 Subject: [PATCH] WIP: fix TQRootBean.exists() when used with .or() --- .../java/io/ebean/typequery/TQRootBean.java | 8 +++--- .../test/java/org/example/domain/Contact.java | 8 +++++- .../example/domain/finder/ContactFinder.java | 18 ++++++++++++ .../org/querytest/QCustomerAndOrTest.java | 28 +++++++++++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 ebean-querybean/src/test/java/org/example/domain/finder/ContactFinder.java diff --git a/ebean-querybean/src/main/java/io/ebean/typequery/TQRootBean.java b/ebean-querybean/src/main/java/io/ebean/typequery/TQRootBean.java index 01f007553..148b201ea 100644 --- a/ebean-querybean/src/main/java/io/ebean/typequery/TQRootBean.java +++ b/ebean-querybean/src/main/java/io/ebean/typequery/TQRootBean.java @@ -745,7 +745,7 @@ public abstract class TQRootBean { * Add EXISTS sub-query predicate. */ public R exists(Query subQuery) { - query.where().exists(subQuery); + peekExprList().exists(subQuery); return root; } @@ -753,7 +753,7 @@ public abstract class TQRootBean { * Add NOT EXISTS sub-query predicate. */ public R notExists(Query subQuery) { - query.where().notExists(subQuery); + peekExprList().notExists(subQuery); return root; } @@ -764,7 +764,7 @@ public abstract class TQRootBean { * @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values. */ public final R exists(String sqlSubQuery, Object... bindValues) { - query().where().exists(sqlSubQuery, bindValues); + peekExprList().exists(sqlSubQuery, bindValues); return root; } @@ -775,7 +775,7 @@ public abstract class TQRootBean { * @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values. */ public final R notExists(String sqlSubQuery, Object... bindValues) { - query().where().notExists(sqlSubQuery, bindValues); + peekExprList().notExists(sqlSubQuery, bindValues); return root; } diff --git a/ebean-querybean/src/test/java/org/example/domain/Contact.java b/ebean-querybean/src/test/java/org/example/domain/Contact.java index 7d2554f57..505cb556a 100644 --- a/ebean-querybean/src/test/java/org/example/domain/Contact.java +++ b/ebean-querybean/src/test/java/org/example/domain/Contact.java @@ -1,8 +1,9 @@ package org.example.domain; import io.ebean.annotation.DbArray; - import jakarta.persistence.*; +import org.example.domain.finder.ContactFinder; + import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.time.ZonedDateTime; @@ -17,6 +18,11 @@ import java.util.Map; @Table(name = "be_contact") public class Contact extends BaseModel { + /** + * Convenience Finder for 'active record' style. + */ + public static final ContactFinder find = new ContactFinder(); + @DbArray List<@Size(max=20) String> phoneNumbers = new ArrayList<>(); diff --git a/ebean-querybean/src/test/java/org/example/domain/finder/ContactFinder.java b/ebean-querybean/src/test/java/org/example/domain/finder/ContactFinder.java new file mode 100644 index 000000000..42f0daccb --- /dev/null +++ b/ebean-querybean/src/test/java/org/example/domain/finder/ContactFinder.java @@ -0,0 +1,18 @@ +package org.example.domain.finder; + +import io.ebean.Finder; +import org.example.domain.Contact; +import org.example.domain.query.QContact; + +/** + */ +public class ContactFinder extends Finder { + + public ContactFinder() { + super(Contact.class); + } + + public QContact typed() { + return new QContact(); + } +} diff --git a/ebean-querybean/src/test/java/org/querytest/QCustomerAndOrTest.java b/ebean-querybean/src/test/java/org/querytest/QCustomerAndOrTest.java index b930c1509..2025b6d79 100644 --- a/ebean-querybean/src/test/java/org/querytest/QCustomerAndOrTest.java +++ b/ebean-querybean/src/test/java/org/querytest/QCustomerAndOrTest.java @@ -1,6 +1,8 @@ package org.querytest; +import org.example.domain.Contact; import org.example.domain.Customer; +import org.example.domain.query.QCustomer; import org.junit.jupiter.api.Test; import java.time.LocalDate; @@ -9,6 +11,8 @@ import java.time.ZoneId; import java.util.Date; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; + public class QCustomerAndOrTest { @Test @@ -55,6 +59,30 @@ public class QCustomerAndOrTest { } + @Test + public void testOrWithExists() { + QCustomer query = Customer.find.typed() + .alias("customer") + .or() + .name.eq("Superman") + .exists(Contact.find.typed() + .alias("contact") + .firstName.eq("Superman") + .raw("contact.customer_id = customer.id") + .query() + ) + .endOr() + .select(QCustomer.alias().id); + + query.findList(); + + assertThat(query.getGeneratedSql()).isEqualTo( + "select customer.id from be_customer customer where (" + + "customer.name = ? or exists (select 1 from be_contact contact where " + + "contact.first_name = ? and contact.customer_id = customer.id))" + ); + } + private Date fiveDaysAgo() { LocalDateTime fiveDaysAgo = LocalDate.now().atStartOfDay().minusDays(5); return new Date(fiveDaysAgo.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());