Skip to content

Commit 6098fb3

Browse files
committed
1 parent 9720f6b commit 6098fb3

File tree

17 files changed

+220
-198
lines changed

17 files changed

+220
-198
lines changed

project/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
group=org.babyfish.jimmer
2-
version=0.9.63
2+
version=0.9.64

project/jimmer-core/src/main/java/org/babyfish/jimmer/impl/util/Keywords.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ public class Keywords {
8181
"immutableType",
8282
"fieldMap",
8383
"__isSimpleFetcher",
84-
"__shownPropIds",
85-
"__hiddenPropIds",
8684

8785
// KNonNullTableEx
8886
"get",

project/jimmer-spring-boot-starter/src/main/java/org/babyfish/jimmer/spring/cfg/JimmerProperties.java

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class JimmerProperties {
3838
private final int maxJoinFetchDepth;
3939

4040
@NotNull
41-
private final DatabaseValidation databaseValidation;
41+
private final DatabaseValidationMode databaseValidationMode;
4242

4343
@NotNull
4444
private final TriggerType triggerType;
@@ -96,8 +96,8 @@ public JimmerProperties(
9696
boolean inlineSqlVariables,
9797
@Nullable ReferenceFetchType defaultReferenceFetchType,
9898
@Nullable Integer maxJoinFetchDepth,
99-
@Deprecated @Nullable DatabaseValidationMode databaseValidationMode,
100-
@Nullable DatabaseValidation databaseValidation,
99+
@Nullable DatabaseValidationMode databaseValidationMode,
100+
@Deprecated @Nullable DatabaseValidation databaseValidation,
101101
@Nullable TriggerType triggerType,
102102
@Nullable Boolean defaultDissociationActionCheckable, // Default value is true, so use `Boolean`
103103
@Nullable IdOnlyTargetCheckingLevel idOnlyTargetCheckingLevel,
@@ -190,17 +190,12 @@ public JimmerProperties(
190190
"\"jimmer.database-validation-mode(deprecated)\""
191191
);
192192
}
193-
if (databaseValidation != null) {
194-
this.databaseValidation = databaseValidation;
193+
if (databaseValidationMode != null) {
194+
this.databaseValidationMode = databaseValidationMode;
195+
} else if (databaseValidation != null) {
196+
this.databaseValidationMode = databaseValidation.getMode();
195197
} else {
196-
this.databaseValidation =
197-
new DatabaseValidation(
198-
databaseValidationMode != null ?
199-
databaseValidationMode :
200-
DatabaseValidationMode.NONE,
201-
null,
202-
null
203-
);
198+
this.databaseValidationMode = DatabaseValidationMode.NONE;
204199
}
205200
this.triggerType = triggerType != null ? triggerType : TriggerType.BINLOG_ONLY;
206201
this.defaultDissociationActionCheckable =
@@ -298,7 +293,7 @@ public int getMaxJoinFetchDepth() {
298293

299294
@NotNull
300295
public DatabaseValidation getDatabaseValidation() {
301-
return databaseValidation;
296+
return new DatabaseValidation(databaseValidationMode, null, null);
302297
}
303298

304299
@NotNull
@@ -451,7 +446,7 @@ public String toString() {
451446
", showSql=" + showSql +
452447
", prettySql=" + prettySql +
453448
", inlineSqlVariables=" + inlineSqlVariables +
454-
", databaseValidation=" + databaseValidation +
449+
", databaseValidationMode=" + databaseValidationMode +
455450
", triggerType=" + triggerType +
456451
", defaultDissociationActionCheckable=" + defaultDissociationActionCheckable +
457452
", idOnlyTargetCheckingLevel=" + idOnlyTargetCheckingLevel +

project/jimmer-sql-kotlin/src/main/kotlin/org/babyfish/jimmer/sql/kt/KTransientResolver.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ import org.babyfish.jimmer.sql.loader.AbstractDataLoader
66
import java.sql.Connection
77
import java.util.*
88

9+
/**
10+
* @param [ID] The id type of current entity
11+
* @param [V] The calculated type, there are three possibilities
12+
* - If the calculated property is NOT association,
13+
* `V` should be the property type
14+
* - If the calculated property is associated reference,
15+
* `V`should be the associated-id type
16+
* - If the calculated property is associated list,
17+
* `V` should be the type of list whose elements
18+
* are associated ids
19+
*/
920
interface KTransientResolver<ID: Any, V> : TransientResolver<ID, V> {
1021

1122
/**

project/jimmer-sql-kotlin/src/test/kotlin/org/babyfish/jimmer/sql/kt/model/hr/Department.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,8 @@ interface Department {
3232

3333
@Formula(sql = "(select count(*) from employee where department_id = %alias.id)")
3434
val employeeCount: Long
35+
36+
@Formula(dependencies = ["id", "name"])
37+
val description: String
38+
get() = "$id-${name.uppercase()}"
3539
}

project/jimmer-sql-kotlin/src/test/kotlin/org/babyfish/jimmer/sql/kt/query/JoinFetchTest.kt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import org.babyfish.jimmer.sql.kt.model.TreeNode
99
import org.babyfish.jimmer.sql.kt.model.classic.book.*
1010
import org.babyfish.jimmer.sql.kt.model.classic.store.name
1111
import org.babyfish.jimmer.sql.kt.model.fetchBy
12+
import org.babyfish.jimmer.sql.kt.model.hr.Employee
13+
import org.babyfish.jimmer.sql.kt.model.hr.fetchBy
1214
import org.babyfish.jimmer.sql.kt.model.id
1315
import org.babyfish.jimmer.sql.kt.model.inheritance.Administrator
1416
import org.babyfish.jimmer.sql.kt.model.inheritance.fetchBy
@@ -278,4 +280,46 @@ class JoinFetchTest : AbstractQueryTest() {
278280
)
279281
}
280282
}
283+
284+
@Test
285+
fun testIssue948() {
286+
executeAndExpect(
287+
sqlClient.createQuery(Employee::class) {
288+
select(
289+
table.fetchBy {
290+
employeeName()
291+
department(ReferenceFetchType.JOIN_ALWAYS) {
292+
description()
293+
}
294+
}
295+
)
296+
}
297+
) {
298+
sql(
299+
"""select tb_1_.ID, tb_1_.NAME, tb_2_.ID, tb_2_.NAME
300+
|from EMPLOYEE tb_1_
301+
|left join DEPARTMENT tb_2_ on tb_1_.DEPARTMENT_ID = tb_2_.ID
302+
|where tb_1_.DELETED_UUID is null""".trimMargin()
303+
)
304+
rows(
305+
"""[
306+
|--->{
307+
|--->--->"id":"1",
308+
|--->--->"employeeName":"Sam",
309+
|--->--->"department":{
310+
|--->--->--->"id":"1",
311+
|--->--->--->"description":"1-MARKET"
312+
|--->--->}
313+
|--->},{
314+
|--->--->"id":"2",
315+
|--->--->"employeeName":"Jessica",
316+
|--->--->"department":{
317+
|--->--->--->"id":"1",
318+
|--->--->--->"description":"1-MARKET"
319+
|--->--->}
320+
|--->}
321+
|]""".trimMargin()
322+
)
323+
}
324+
}
281325
}

project/jimmer-sql/src/main/java/org/babyfish/jimmer/sql/TransientResolver.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,17 @@
1414
/**
1515
* Only for java, kotlin developers should use `KTransientResolver`
1616
*
17-
* @param <ID>
18-
* @param <V>
17+
* @param <ID> The id type of current entity
18+
* @param <V> The calculated type, there are three possibilities
19+
* <ul>
20+
* <li>If the calculated property is NOT association,
21+
* {@code V} should be the property type</li>
22+
* <li>If the calculated property is associated reference,
23+
* {@code V} should be the associated-id type</li>
24+
* <li>If the calculated property is associated list,
25+
* {@code V} should be the type of list whose elements
26+
* are associated ids.</li>
27+
* </ul>
1928
*/
2029
public interface TransientResolver<ID, V> extends PropCacheInvalidator {
2130

project/jimmer-sql/src/main/java/org/babyfish/jimmer/sql/ast/query/Filterable.java

Lines changed: 24 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -36,56 +36,25 @@ public interface Filterable {
3636
* Therefore, before {@code whereIf} is executed, {@code ge(null)}
3737
* already causes an exception.
3838
*
39-
* <p>For this reason, whereIf provides an overloaded form with a lambda parameter:</p>
39+
* <p>For this reason, {@code whereIf} provides an overloaded form with a lambda parameter:</p>
4040
* <pre>{@code
4141
* whereIf(minPrice != null, () -> table.price().ge(minPrice))
4242
* }</pre>
4343
* Although this overloaded form can solve this problem,
4444
* it ultimately adds a mental burden during development.
4545
*
4646
* <p>Therefore, Jimmer provides {@code Dynamic Predicates}</p>
47-
* <table>
48-
* <tr>
49-
* <td><b>Java</b></td>
50-
* <td><b>Kotlin</b></td>
51-
* </tr>
52-
* <tr>
53-
* <td>eqIf</td>
54-
* <td>eq?</td>
55-
* </tr>
56-
* <tr>
57-
* <td>neIf</td>
58-
* <td>ne?</td>
59-
* </tr>
60-
* <tr>
61-
* <td>ltIf</td>
62-
* <td>lt?</td>
63-
* </tr>
64-
* <tr>
65-
* <td>leIf</td>
66-
* <td>le?</td>
67-
* </tr>
68-
* <tr>
69-
* <td>gtIf</td>
70-
* <td>gt?</td>
71-
* </tr>
72-
* <tr>
73-
* <td>geIf</td>
74-
* <td>ge?</td>
75-
* </tr>
76-
* <tr>
77-
* <td>likeIf</td>
78-
* <td>like?</td>
79-
* </tr>
80-
* <tr>
81-
* <td>ilikeIf</td>
82-
* <td>ilike?</td>
83-
* </tr>
84-
* <tr>
85-
* <td>betweenIf</td>
86-
* <td>bwtween?</td>
87-
* </tr>
88-
* </table>
47+
*
48+
* <ul>
49+
* <li>
50+
* <b>Java</b>:
51+
* eqIf, neIf, ltIf, leIf, gtIf, geIf, likeIf, ilikeIf, betweenIf
52+
* </li>
53+
* <li>
54+
* <b>Kotlin</b>:
55+
* eq?, ne?, lt?, le?, gt?, ge?, like?, ilike?, betweenIf?
56+
* </li>
57+
* </ul>
8958
*
9059
* Taking Java's {@code geIf} as an example, this functionality
9160
* is ultimately implemented like this.
@@ -123,56 +92,25 @@ default Filterable whereIf(boolean condition, Predicate predicate) {
12392
* Therefore, before {@code whereIf} is executed, {@code ge(null)}
12493
* already causes an exception.
12594
*
126-
* <p>For this reason, whereIf provides an overloaded form with a lambda parameter:</p>
95+
* <p>For this reason, {@code whereIf} provides an overloaded form with a lambda parameter:</p>
12796
* <pre>{@code
12897
* whereIf(minPrice != null, () -> table.price().ge(minPrice))
12998
* }</pre>
13099
* Although this overloaded form can solve this problem,
131100
* it ultimately adds a mental burden during development.
132101
*
133102
* <p>Therefore, Jimmer provides {@code Dynamic Predicate}</p>
134-
* <table>
135-
* <tr>
136-
* <td><b>Java</b></td>
137-
* <td><b>Kotlin</b></td>
138-
* </tr>
139-
* <tr>
140-
* <td>eqIf</td>
141-
* <td>eq?</td>
142-
* </tr>
143-
* <tr>
144-
* <td>neIf</td>
145-
* <td>ne?</td>
146-
* </tr>
147-
* <tr>
148-
* <td>ltIf</td>
149-
* <td>lt?</td>
150-
* </tr>
151-
* <tr>
152-
* <td>leIf</td>
153-
* <td>le?</td>
154-
* </tr>
155-
* <tr>
156-
* <td>gtIf</td>
157-
* <td>gt?</td>
158-
* </tr>
159-
* <tr>
160-
* <td>geIf</td>
161-
* <td>ge?</td>
162-
* </tr>
163-
* <tr>
164-
* <td>likeIf</td>
165-
* <td>like?</td>
166-
* </tr>
167-
* <tr>
168-
* <td>ilikeIf</td>
169-
* <td>ilike?</td>
170-
* </tr>
171-
* <tr>
172-
* <td>betweenIf</td>
173-
* <td>bwtween?</td>
174-
* </tr>
175-
* </table>
103+
*
104+
* <ul>
105+
* <li>
106+
* <b>Java</b>:
107+
* eqIf, neIf, ltIf, leIf, gtIf, geIf, likeIf, ilikeIf, betweenIf
108+
* </li>
109+
* <li>
110+
* <b>Kotlin</b>:
111+
* eq?, ne?, lt?, le?, gt?, ge?, like?, ilike?, betweenIf?
112+
* </li>
113+
* </ul>
176114
*
177115
* Taking Java's {@code geIf} as an example, this functionality
178116
* is ultimately implemented like this.

project/jimmer-sql/src/main/java/org/babyfish/jimmer/sql/fetcher/impl/FetcherContext.java

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,11 @@ private FetcherContext(JSqlClientImplementor sqlClient, Connection con) {
5151
public void addAll(FetchPath path, Fetcher<?> fetcher, Collection<@Nullable DraftSpi> drafts) {
5252
for (DraftSpi draft : drafts) {
5353
if (draft != null) {
54-
add(path, fetcher, draft);
54+
new TaskAdder(path, draft).visit(fetcher);
5555
}
5656
}
5757
}
5858

59-
@SuppressWarnings("unchecked")
60-
private void add(FetchPath path, Fetcher<?> fetcher, DraftSpi draft) {
61-
setVisibility(draft, (FetcherImplementor<?>) fetcher);
62-
new TaskAdder(path, draft).visit(fetcher);
63-
}
64-
6559
private class TaskAdder extends JoinFetchFieldVisitor {
6660

6761
private final FetchPath path;
@@ -139,28 +133,6 @@ public void execute() {
139133
}
140134
}
141135

142-
static void setVisibility(DraftSpi draft, FetcherImplementor<?> fetcher) {
143-
for (PropId shownPropId : fetcher.__shownPropIds()) {
144-
draft.__show(shownPropId, true);
145-
}
146-
for (PropId hiddenPropId : fetcher.__hiddenPropIds()) {
147-
draft.__show(hiddenPropId, false);
148-
}
149-
for (Field field : fetcher.getFieldMap().values()) {
150-
FetcherImplementor<?> childFetcher = (FetcherImplementor<?>) field.getChildFetcher(true);
151-
ImmutableProp prop = field.getProp();
152-
if (childFetcher != null && prop.isEmbedded(EmbeddedLevel.SCALAR)) {
153-
PropId propId = prop.getId();
154-
if (draft.__isLoaded(propId)) {
155-
DraftSpi childDraft = (DraftSpi) draft.__get(propId);
156-
if (childDraft != null) {
157-
setVisibility(childDraft, childFetcher);
158-
}
159-
}
160-
}
161-
}
162-
}
163-
164136
private static class FetchedField {
165137

166138
final FetchPath path;

0 commit comments

Comments
 (0)