Skip to content

Commit 82e5210

Browse files
authoredApr 7, 2022
fix: support EQ/NE nullable criteria values for Java scalars (#302)
1 parent ae420ed commit 82e5210

File tree

4 files changed

+112
-11
lines changed

4 files changed

+112
-11
lines changed
 

‎graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/JpaPredicateBuilder.java

+32-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@
2828
import java.time.OffsetDateTime;
2929
import java.time.ZonedDateTime;
3030
import java.util.ArrayList;
31+
import java.util.Arrays;
32+
import java.util.Calendar;
3133
import java.util.Collection;
3234
import java.util.Date;
3335
import java.util.HashMap;
36+
import java.util.LinkedHashSet;
3437
import java.util.List;
3538
import java.util.Map;
3639
import java.util.Set;
@@ -66,19 +69,23 @@
6669
* <li> java.util.Date </li>
6770
* <li> java.time.LocalDate </li>
6871
* <li> java.time.LocalDateTime </>
72+
* <li> java.time.OffsetDateTime </>
73+
* <li> java.time.ZonedDateTime </>
6974
* <li> java.time.Instant </li>
7075
* <li> java.time.LocalTime </li>
7176
* <li> java.util.Calendar </li>
7277
* <li> java.sql.Date </li>
7378
* <li> java.sql.Time </li>
7479
* <li> java.sql.Timestamp </li>
80+
* <li> java.util.UUID </li>
7581
* </ul>
7682
*
7783
*/
7884
class JpaPredicateBuilder {
7985

8086
public static final Map<Class<?>, Class<?>> WRAPPERS_TO_PRIMITIVES = new HashMap<Class<?>, Class<?>>();
8187
public static final Map<Class<?>, Class<?>> PRIMITIVES_TO_WRAPPERS = new HashMap<Class<?>, Class<?>>();
88+
public static final Set<Class<?>> JAVA_SCALARS = new LinkedHashSet<>();
8289

8390
static {
8491
PRIMITIVES_TO_WRAPPERS.put(boolean.class, Boolean.class);
@@ -100,6 +107,30 @@ class JpaPredicateBuilder {
100107
WRAPPERS_TO_PRIMITIVES.put(Long.class, long.class);
101108
WRAPPERS_TO_PRIMITIVES.put(Short.class, short.class);
102109
WRAPPERS_TO_PRIMITIVES.put(Void.class, void.class);
110+
111+
JAVA_SCALARS.addAll(Arrays.asList(Boolean.class,
112+
Byte.class,
113+
Character.class,
114+
Double.class,
115+
Float.class,
116+
Integer.class,
117+
Long.class,
118+
Short.class,
119+
BigInteger.class,
120+
BigDecimal.class,
121+
String.class,
122+
Date.class,
123+
LocalDate.class,
124+
LocalDateTime.class,
125+
ZonedDateTime.class,
126+
Instant.class,
127+
LocalTime.class,
128+
Calendar.class,
129+
OffsetDateTime.class,
130+
java.sql.Date.class,
131+
java.sql.Time.class,
132+
java.sql.Timestamp.class,
133+
UUID.class));
103134
}
104135

105136
private final CriteriaBuilder cb;
@@ -304,7 +335,6 @@ protected Predicate getFloatingPointPredicate(Path<? extends Number> root, Predi
304335
return null;
305336
}
306337

307-
// TODO: other date types
308338
protected Predicate getDatePredicate(Path<? extends Date> root, PredicateFilter filter) {
309339
if (filter.getValue() != null && filter.getValue() instanceof Date) {
310340
if (filter.getCriterias().contains(PredicateFilter.Criteria.LT)) {
@@ -730,7 +760,7 @@ private Predicate getTypedPredicate(From<?,?> from, Path<?> field, PredicateFilt
730760
if (type.isPrimitive())
731761
type = PRIMITIVES_TO_WRAPPERS.get(type);
732762

733-
if (NullValue.class.isInstance(value) && WRAPPERS_TO_PRIMITIVES.get(type) != null) {
763+
if (NullValue.class.isInstance(value) && JAVA_SCALARS.contains(type)) {
734764
if (criterias.contains(Criteria.EQ)) {
735765
return cb.isNull(field);
736766
} else if (criterias.contains(Criteria.NE)) {

‎graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/GraphQLJpaConverterTests.java

+68-3
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ public void criteriaTester5() {
226226

227227
// then:
228228
assertThat(result).isNotEmpty();
229-
assertThat(result).hasSize(4);
229+
assertThat(result).hasSize(5);
230230
}
231231

232232
@Test
@@ -258,7 +258,7 @@ public void criteriaTester6() {
258258

259259
// then:
260260
assertThat(result).isNotEmpty();
261-
assertThat(result).hasSize(4);
261+
assertThat(result).hasSize(5);
262262
}
263263

264264
@Test // Problem with generating cast() in the where expression
@@ -823,7 +823,72 @@ public void queryTasksVariablesWhereWithEXISTSByNameAndValueCriteria() {
823823

824824
// then
825825
assertThat(result.toString()).isEqualTo(expected);
826-
}
826+
}
827827

828+
@Test
829+
public void testGraphqlTasksQueryWithEQNullValues() {
830+
// @formatter:off
831+
String query =
832+
"query {" +
833+
" Tasks(" +
834+
" page: { start: 1, limit: 100 }" +
835+
" where: { status: { IN: [CREATED, ASSIGNED] }, dueDate: { EQ: null } }" +
836+
" ) {" +
837+
" select {" +
838+
" id" +
839+
" businessKey" +
840+
" name" +
841+
" status" +
842+
" priority(orderBy: DESC)" +
843+
" dueDate(orderBy: ASC)" +
844+
" assignee" +
845+
" }" +
846+
" }" +
847+
"}";
848+
// @formatter:on
849+
850+
Object result = executor.execute(query).getData();
851+
852+
String expected = "{Tasks={select=[" +
853+
"{id=2, businessKey=null, name=task2, status=CREATED, priority=10, dueDate=null, assignee=assignee}, " +
854+
"{id=4, businessKey=null, name=task4, status=CREATED, priority=10, dueDate=null, assignee=assignee}, " +
855+
"{id=6, businessKey=bk6, name=task6, status=ASSIGNED, priority=10, dueDate=null, assignee=assignee}, " +
856+
"{id=3, businessKey=null, name=task3, status=CREATED, priority=5, dueDate=null, assignee=assignee}" +
857+
"]}}";
858+
859+
assertThat(result.toString()).isEqualTo(expected);
860+
}
861+
862+
@Test
863+
public void testGraphqlTasksQueryWithNENullValues() {
864+
// @formatter:off
865+
String query =
866+
"query {" +
867+
" Tasks(" +
868+
" page: { start: 1, limit: 100 }" +
869+
" where: { status: { IN: [ASSIGNED, COMPLETED] }, businessKey: { NE: null } }" +
870+
" ) {" +
871+
" select {" +
872+
" id" +
873+
" businessKey" +
874+
" name" +
875+
" status" +
876+
" priority(orderBy: DESC)" +
877+
" dueDate(orderBy: ASC)" +
878+
" assignee" +
879+
" }" +
880+
" }" +
881+
"}";
882+
// @formatter:on
883+
884+
Object result = executor.execute(query).getData();
885+
886+
String expected = "{Tasks={select=[" +
887+
"{id=6, businessKey=bk6, name=task6, status=ASSIGNED, priority=10, dueDate=null, assignee=assignee}, " +
888+
"{id=1, businessKey=bk1, name=task1, status=COMPLETED, priority=5, dueDate=null, assignee=assignee}" +
889+
"]}}";
890+
891+
assertThat(result.toString()).isEqualTo(expected);
892+
}
828893

829894
}

‎graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/converter/model/TaskEntity.java

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public class TaskEntity extends ActivitiEntityMetadata {
3737
private String assignee;
3838
private String name;
3939
private String description;
40+
private String businessKey;
4041
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
4142
private Date createdDate;
4243
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@@ -157,6 +158,10 @@ public String getDescription() {
157158
return description;
158159
}
159160

161+
public String getBusinessKey() { return businessKey; }
162+
163+
public void setBusinessKey(String businessKey) { this.businessKey = businessKey; }
164+
160165
public Date getCreatedDate() {
161166
return createdDate;
162167
}

‎graphql-jpa-query-schema/src/test/resources/GraphQLJpaConverterTests.sql

+7-6
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ insert into json_entity (id, first_name, last_name, attributes) values
33
(1, 'john', 'doe', '{"attr":{"key":["1","2","3","4","5"]}}'),
44
(2, 'joe', 'smith', '{"attr":["1","2","3","4","5"]}');
55

6-
insert into TASK (id, assignee, created_date, description, due_date, last_modified, last_modified_from, last_modified_to, name, priority, process_definition_id, process_instance_id, status, owner, claimed_date) values
7-
('1', 'assignee', CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task1', 5, 'process_definition_id', 0, 'COMPLETED' , 'owner', null),
8-
('2', 'assignee', CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task2', 10, 'process_definition_id', 0, 'CREATED' , 'owner', null),
9-
('3', 'assignee', CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task3', 5, 'process_definition_id', 0, 'CREATED' , 'owner', null),
10-
('4', 'assignee', CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task4', 10, 'process_definition_id', 1, 'CREATED' , 'owner', null),
11-
('5', 'assignee', CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task5', 5, 'process_definition_id', 1, 'COMPLETED' , 'owner', null);
6+
insert into task (id, assignee, business_key, created_date, description, due_date, last_modified, last_modified_from, last_modified_to, name, priority, process_definition_id, process_instance_id, status, owner, claimed_date) values
7+
('1', 'assignee', 'bk1', CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task1', 5, 'process_definition_id', 0, 'COMPLETED' , 'owner', null),
8+
('2', 'assignee', null, CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task2', 10, 'process_definition_id', 0, 'CREATED' , 'owner', null),
9+
('3', 'assignee', null, CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task3', 5, 'process_definition_id', 0, 'CREATED' , 'owner', null),
10+
('4', 'assignee', null, CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task4', 10, 'process_definition_id', 1, 'CREATED' , 'owner', null),
11+
('5', 'assignee', null, CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task5', 10, 'process_definition_id', 1, 'COMPLETED' , 'owner', null),
12+
('6', 'assignee', 'bk6', CURRENT_TIMESTAMP, 'description', null, null, null, null, 'task6', 10, 'process_definition_id', 0, 'ASSIGNED' , 'owner', null);
1213

1314
insert into PROCESS_VARIABLE (create_time, execution_id, last_updated_time, name, process_instance_id, type, value) values
1415
(CURRENT_TIMESTAMP, 'execution_id', CURRENT_TIMESTAMP, 'document', 1, 'json', '{"value":{"key":["1","2","3","4","5"]}}');

0 commit comments

Comments
 (0)
Please sign in to comment.