Skip to content

Commit dbe81bd

Browse files
authored
Merge pull request #3180 from FOCONIS/bugfix/setId-or-idEq-in-subquery
BUG: Using a subquery with idEq or setId is missing the bind value
2 parents 019ef43 + 2e2b384 commit dbe81bd

File tree

2 files changed

+126
-5
lines changed

2 files changed

+126
-5
lines changed

ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@
2121
import java.sql.PreparedStatement;
2222
import java.sql.SQLException;
2323
import java.sql.Timestamp;
24-
import java.util.Collections;
25-
import java.util.HashSet;
26-
import java.util.List;
27-
import java.util.Set;
24+
import java.util.*;
2825

2926
import static java.lang.System.Logger.Level.WARNING;
3027

@@ -303,7 +300,20 @@ private String deriveOrderByWithMany(BeanPropertyAssocMany<?> manyProp) {
303300
* Return the bind values for the where expression.
304301
*/
305302
public List<Object> whereExprBindValues() {
306-
return where == null ? Collections.emptyList() : where.bindValues();
303+
if (idValue == null && where == null) {
304+
return Collections.emptyList();
305+
}
306+
if (where == null) {
307+
return List.of(idValue);
308+
}
309+
if (idValue == null) {
310+
return where.bindValues();
311+
}
312+
313+
List<Object> bindValues = new ArrayList<>();
314+
bindValues.add(idValue);
315+
bindValues.addAll(where.bindValues());
316+
return Collections.unmodifiableList(bindValues);
307317
}
308318

309319
/**
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package org.tests.query;
2+
3+
import io.ebean.DB;
4+
import io.ebean.test.LoggedSql;
5+
import io.ebean.xtest.BaseTestCase;
6+
import org.junit.jupiter.api.AfterEach;
7+
import org.junit.jupiter.api.BeforeEach;
8+
import org.junit.jupiter.api.Test;
9+
import org.tests.model.basic.Order;
10+
import org.tests.model.basic.Person;
11+
import org.tests.model.basic.ResetBasicData;
12+
13+
import java.util.List;
14+
15+
import static org.assertj.core.api.Assertions.assertThat;
16+
17+
public class TestQuerySubquery extends BaseTestCase {
18+
19+
private Long robId;
20+
21+
@BeforeEach
22+
public void setup() {
23+
ResetBasicData.reset();
24+
25+
Person rob = new Person();
26+
rob.setName("Rob");
27+
rob.setSurname("Test");
28+
DB.save(rob);
29+
robId = rob.getId();
30+
31+
DB.getDefault().pluginApi().cacheManager().clearAll();
32+
}
33+
34+
@AfterEach
35+
public void cleanup() {
36+
DB.delete(Person.class, robId);
37+
}
38+
39+
@Test
40+
public void testWithoutSubquery() {
41+
42+
Person contact = DB.find(Person.class)
43+
.where()
44+
.idEq(robId)
45+
.findOne();
46+
47+
LoggedSql.start();
48+
List<Order> orders = DB.find(Order.class)
49+
.where()
50+
.eq("customer.name", contact.getName())
51+
.findList();
52+
53+
assertThat(orders).hasSize(3);
54+
assertThat(LoggedSql.stop())
55+
.hasSize(1)
56+
.first().asString()
57+
.contains("--bind(" + contact.getName() + ")")
58+
.contains("kcustomer_id where t1.name = ?");
59+
}
60+
61+
@Test
62+
public void testEqSubqueryWithIdEq() {
63+
LoggedSql.start();
64+
List<Order> orders = DB.find(Order.class)
65+
.where()
66+
.eq("customer.name", DB.find(Person.class).alias("sq").select("name").where().idEq(robId).query())
67+
.findList();
68+
69+
assertThat(orders).hasSize(3);
70+
assertThat(LoggedSql.stop())
71+
.hasSize(1)
72+
.first().asString()
73+
.contains("--bind(" + robId + ")")
74+
.contains("t1.name = (select sq.NAME from PERSONS sq where sq.ID = ?)");
75+
}
76+
77+
@Test
78+
public void testEqSubqueryWithSetId() {
79+
LoggedSql.start();
80+
81+
List<Order> orders = DB.find(Order.class)
82+
.where()
83+
.eq("customer.name", DB.find(Person.class).alias("sq").select("name").setId(robId))
84+
.findList();
85+
86+
assertThat(orders).hasSize(3);
87+
assertThat(LoggedSql.stop())
88+
.hasSize(1)
89+
.first().asString()
90+
.contains("--bind(" + robId + ")")
91+
.contains("t1.name = (select sq.NAME from PERSONS sq where sq.ID = ?)");
92+
}
93+
94+
@Test
95+
public void testEqSubqueryWithEqId() {
96+
LoggedSql.start();
97+
98+
List<Order> orders = DB.find(Order.class)
99+
.where()
100+
.eq("customer.name", DB.find(Person.class).alias("sq").select("name").where().eq("id", robId).query())
101+
.findList();
102+
103+
assertThat(orders).hasSize(3);
104+
assertThat(LoggedSql.stop())
105+
.hasSize(1)
106+
.first().asString()
107+
.contains("--bind(" + robId + ")")
108+
.contains("t1.name = (select sq.NAME from PERSONS sq where sq.ID = ?)");
109+
}
110+
111+
}

0 commit comments

Comments
 (0)