Skip to content

Commit b05c246

Browse files
authored
feat: support nested relationships in where criteria expressions (#108)
* add DroidFunction to StarWars model for example and test, use as primaryFunction in Droid * update SQL for example and tests to create DroidFunction records and reference them in Droid records * update test queryForDroidByName to expect DroidFunction to be nested * add tests for where clauses on many-to-one relationships, the nested one currently failing * that was not the droid I was looking for * move DroidFunction into starwars package * restore DroidFunction into starwars package * update example sql data to include droid_function entity * account for droid_function in newly merged tests * feat: implemented many to one relation criteria expression * chore: clean up code * feat: add nested one-to-many criteria expression support * fix: use default distinct configuration in one-to-many data fetcher * fix: polish test formatting
1 parent 3f9704b commit b05c246

File tree

18 files changed

+653
-157
lines changed

18 files changed

+653
-157
lines changed

graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/Author.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package com.introproventures.graphql.jpa.query.example.books;
1818

19-
import java.util.Collection;
19+
import java.util.Set;
2020

2121
import javax.persistence.Entity;
2222
import javax.persistence.FetchType;
@@ -34,5 +34,5 @@ public class Author {
3434
String name;
3535

3636
@OneToMany(mappedBy="author", fetch=FetchType.LAZY)
37-
Collection<Book> books;
37+
Set<Book> books;
3838
}

graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/books/Book.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,16 @@
2323
import javax.persistence.Id;
2424
import javax.persistence.ManyToOne;
2525

26-
import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreFilter;
27-
import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreOrder;
2826
import lombok.Data;
27+
import lombok.EqualsAndHashCode;
2928

3029
@Data
3130
@Entity
31+
@EqualsAndHashCode(exclude="author")
3232
public class Book {
3333
@Id
3434
Long id;
3535

36-
@GraphQLIgnoreOrder
37-
@GraphQLIgnoreFilter
3836
String title;
3937

4038
@ManyToOne(fetch=FetchType.LAZY)

graphql-jpa-query-example-merge/src/main/java/com/introproventures/graphql/jpa/query/example/starwars/Droid.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
package com.introproventures.graphql.jpa.query.example.starwars;
1818

1919
import javax.persistence.Entity;
20+
import javax.persistence.FetchType;
21+
import javax.persistence.JoinColumn;
22+
import javax.persistence.ManyToOne;
2023

2124
import com.introproventures.graphql.jpa.query.annotation.GraphQLDescription;
2225

@@ -30,6 +33,8 @@
3033
public class Droid extends Character {
3134

3235
@GraphQLDescription("Documents the primary purpose this droid serves")
33-
String primaryFunction;
36+
@ManyToOne(fetch = FetchType.LAZY)
37+
@JoinColumn(name = "primary_function")
38+
DroidFunction primaryFunction;
3439

3540
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.introproventures.graphql.jpa.query.example.starwars;
2+
3+
import javax.persistence.Entity;
4+
import javax.persistence.Id;
5+
import javax.persistence.Table;
6+
7+
import com.introproventures.graphql.jpa.query.annotation.GraphQLDescription;
8+
import lombok.Data;
9+
import lombok.EqualsAndHashCode;
10+
11+
12+
@Entity(name = "droidFunction")
13+
@Table(name = "droid_function")
14+
@GraphQLDescription("Represents the functions a droid can have")
15+
@Data
16+
@EqualsAndHashCode()
17+
public class DroidFunction {
18+
19+
@Id
20+
@GraphQLDescription("Primary Key for the DroidFunction Class")
21+
String id;
22+
23+
String function;
24+
25+
26+
27+
}

graphql-jpa-query-example-merge/src/main/resources/starwars.sql

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@ insert into CodeList (id, type, code, description, sequence, active, parent_id)
44
(0, 'org.crygier.graphql.model.starwars.Gender', 'Male', 'Male', 1, true, null),
55
(1, 'org.crygier.graphql.model.starwars.Gender', 'Female', 'Female', 2, true, null);
66

7+
-- Insert Droid Functions
8+
insert into droid_function(id, function) values
9+
( '1000', 'Protocol'),
10+
( '1001', 'Astromech');
11+
712
-- Insert Droids
8-
insert into Character (id, name, primaryFunction, dtype) values
9-
('2000', 'C-3PO', 'Protocol', 'Droid'),
10-
('2001', 'R2-D2', 'Astromech', 'Droid');
13+
insert into character (id, name, primary_function, dtype) values
14+
('2000', 'C-3PO', '1000', 'Droid'),
15+
('2001', 'R2-D2', '1001', 'Droid');
1116

1217
-- Insert Humans
1318
insert into character (id, name, homePlanet, favorite_droid_id, dtype, gender_code_id) values

graphql-jpa-query-example/src/main/java/com/introproventures/graphql/jpa/query/example/starwars/Droid.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
package com.introproventures.graphql.jpa.query.example.starwars;
1818

1919
import javax.persistence.Entity;
20+
import javax.persistence.FetchType;
21+
import javax.persistence.JoinColumn;
22+
import javax.persistence.ManyToOne;
2023

2124
import com.introproventures.graphql.jpa.query.annotation.GraphQLDescription;
22-
2325
import lombok.Data;
2426
import lombok.EqualsAndHashCode;
2527

@@ -29,7 +31,13 @@
2931
@EqualsAndHashCode(callSuper=true)
3032
public class Droid extends Character {
3133

32-
@GraphQLDescription("Documents the primary purpose this droid serves")
33-
String primaryFunction;
34+
@ManyToOne(fetch = FetchType.LAZY)
35+
@JoinColumn(name = "primary_function")
36+
DroidFunction primaryFunction;
3437

38+
//description moved to getter to test it gets picked up
39+
@GraphQLDescription("Documents the primary purpose this droid serves")
40+
public DroidFunction getPrimaryFunction() {
41+
return(primaryFunction);
42+
}
3543
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.introproventures.graphql.jpa.query.example.starwars;
2+
3+
import javax.persistence.Entity;
4+
import javax.persistence.Id;
5+
import javax.persistence.Table;
6+
7+
import com.introproventures.graphql.jpa.query.annotation.GraphQLDescription;
8+
import lombok.Data;
9+
import lombok.EqualsAndHashCode;
10+
11+
12+
@Entity(name = "droidFunction")
13+
@Table(name = "droid_function")
14+
@GraphQLDescription("Represents the functions a droid can have")
15+
@Data
16+
@EqualsAndHashCode()
17+
public class DroidFunction {
18+
19+
@Id
20+
@GraphQLDescription("Primary Key for the DroidFunction Class")
21+
String id;
22+
23+
String function;
24+
25+
26+
27+
}
Lines changed: 109 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,109 @@
1-
-- Insert Code Lists
2-
insert into code_list (id, type, code, description, sequence, active, parent_id) values
3-
(0, 'org.crygier.graphql.model.starwars.Gender', 'Male', 'Male', 1, true, null),
4-
(1, 'org.crygier.graphql.model.starwars.Gender', 'Female', 'Female', 2, true, null);
5-
6-
-- Insert Droids
7-
insert into character (id, name, primary_function, dtype) values
8-
('2000', 'C-3PO', 'Protocol', 'Droid'),
9-
('2001', 'R2-D2', 'Astromech', 'Droid');
10-
11-
-- Insert Humans
12-
insert into character (id, name, home_planet, favorite_droid_id, dtype, gender_code_id) values
13-
('1000', 'Luke Skywalker', 'Tatooine', '2000', 'Human', 0),
14-
('1001', 'Darth Vader', 'Tatooine', '2001', 'Human', 0),
15-
('1002', 'Han Solo', NULL, NULL, 'Human', 0),
16-
('1003', 'Leia Organa', 'Alderaan', NULL, 'Human', 1),
17-
('1004', 'Wilhuff Tarkin', NULL, NULL, 'Human', 0);
18-
19-
-- Luke's friends
20-
insert into character_friends (source_id, friend_id) values
21-
('1000', '1002'),
22-
('1000', '1003'),
23-
('1000', '2000'),
24-
('1000', '2001');
25-
26-
-- Luke Appears in
27-
insert into character_appears_in (character_id, appears_in) values
28-
('1000', 3),
29-
('1000', 4),
30-
('1000', 5),
31-
('1000', 6);
32-
33-
-- Vader's friends
34-
insert into character_friends (source_id, friend_id) values
35-
('1001', '1004');
36-
37-
-- Vader Appears in
38-
insert into character_appears_in (character_id, appears_in) values
39-
('1001', 3),
40-
('1001', 4),
41-
('1001', 5);
42-
43-
-- Solo's friends
44-
insert into character_friends (source_id, friend_id) values
45-
('1002', '1000'),
46-
('1002', '1003'),
47-
('1002', '2001');
48-
49-
-- Solo Appears in
50-
insert into character_appears_in (character_id, appears_in) values
51-
('1002', 3),
52-
('1002', 4),
53-
('1002', 5),
54-
('1002', 6);
55-
56-
-- Leia's friends
57-
insert into character_friends (source_id, friend_id) values
58-
('1003', '1000'),
59-
('1003', '1002'),
60-
('1003', '2000'),
61-
('1003', '2001');
62-
63-
-- Leia Appears in
64-
insert into character_appears_in (character_id, appears_in) values
65-
('1003', 3),
66-
('1003', 4),
67-
('1003', 5),
68-
('1003', 6);
69-
70-
-- Wilhuff's friends
71-
insert into character_friends (source_id, friend_id) values
72-
('1004', '1001');
73-
74-
-- Wilhuff Appears in
75-
insert into character_appears_in (character_id, appears_in) values
76-
('1004', 3);
77-
78-
-- C3PO's friends
79-
insert into character_friends (source_id, friend_id) values
80-
('2000', '1000'),
81-
('2000', '1002'),
82-
('2000', '1003'),
83-
('2000', '2001');
84-
85-
-- C3PO Appears in
86-
insert into character_appears_in (character_id, appears_in) values
87-
('2000', 3),
88-
('2000', 4),
89-
('2000', 5),
90-
('2000', 6);
91-
92-
-- R2's friends
93-
insert into character_friends (source_id, friend_id) values
94-
('2001', '1000'),
95-
('2001', '1002'),
96-
('2001', '1003');
97-
98-
-- R2 Appears in
99-
insert into character_appears_in (character_id, appears_in) values
100-
('2001', 3),
101-
('2001', 4),
102-
('2001', 5),
103-
('2001', 6);
104-
1+
-- Insert Code Lists
2+
insert into code_list (id, type, code, description, sequence, active, parent_id) values
3+
(0, 'org.crygier.graphql.model.starwars.Gender', 'Male', 'Male', 1, true, null),
4+
(1, 'org.crygier.graphql.model.starwars.Gender', 'Female', 'Female', 2, true, null);
5+
6+
-- Insert Droid Functions
7+
insert into droid_function(id, function) values
8+
( '1000', 'Protocol'),
9+
( '1001', 'Astromech');
10+
11+
-- Insert Droids
12+
insert into character (id, name, primary_function, dtype) values
13+
('2000', 'C-3PO', '1000', 'Droid'),
14+
('2001', 'R2-D2', '1001', 'Droid');
15+
16+
-- Insert Humans
17+
insert into character (id, name, home_planet, favorite_droid_id, dtype, gender_code_id) values
18+
('1000', 'Luke Skywalker', 'Tatooine', '2000', 'Human', 0),
19+
('1001', 'Darth Vader', 'Tatooine', '2001', 'Human', 0),
20+
('1002', 'Han Solo', NULL, NULL, 'Human', 0),
21+
('1003', 'Leia Organa', 'Alderaan', NULL, 'Human', 1),
22+
('1004', 'Wilhuff Tarkin', NULL, NULL, 'Human', 0);
23+
24+
-- Luke's friends
25+
insert into character_friends (source_id, friend_id) values
26+
('1000', '1002'),
27+
('1000', '1003'),
28+
('1000', '2000'),
29+
('1000', '2001');
30+
31+
-- Luke Appears in
32+
insert into character_appears_in (character_id, appears_in) values
33+
('1000', 3),
34+
('1000', 4),
35+
('1000', 5),
36+
('1000', 6);
37+
38+
-- Vader's friends
39+
insert into character_friends (source_id, friend_id) values
40+
('1001', '1004');
41+
42+
-- Vader Appears in
43+
insert into character_appears_in (character_id, appears_in) values
44+
('1001', 3),
45+
('1001', 4),
46+
('1001', 5);
47+
48+
-- Solo's friends
49+
insert into character_friends (source_id, friend_id) values
50+
('1002', '1000'),
51+
('1002', '1003'),
52+
('1002', '2001');
53+
54+
-- Solo Appears in
55+
insert into character_appears_in (character_id, appears_in) values
56+
('1002', 3),
57+
('1002', 4),
58+
('1002', 5),
59+
('1002', 6);
60+
61+
-- Leia's friends
62+
insert into character_friends (source_id, friend_id) values
63+
('1003', '1000'),
64+
('1003', '1002'),
65+
('1003', '2000'),
66+
('1003', '2001');
67+
68+
-- Leia Appears in
69+
insert into character_appears_in (character_id, appears_in) values
70+
('1003', 3),
71+
('1003', 4),
72+
('1003', 5),
73+
('1003', 6);
74+
75+
-- Wilhuff's friends
76+
insert into character_friends (source_id, friend_id) values
77+
('1004', '1001');
78+
79+
-- Wilhuff Appears in
80+
insert into character_appears_in (character_id, appears_in) values
81+
('1004', 3);
82+
83+
-- C3PO's friends
84+
insert into character_friends (source_id, friend_id) values
85+
('2000', '1000'),
86+
('2000', '1002'),
87+
('2000', '1003'),
88+
('2000', '2001');
89+
90+
-- C3PO Appears in
91+
insert into character_appears_in (character_id, appears_in) values
92+
('2000', 3),
93+
('2000', 4),
94+
('2000', 5),
95+
('2000', 6);
96+
97+
-- R2's friends
98+
insert into character_friends (source_id, friend_id) values
99+
('2001', '1000'),
100+
('2001', '1002'),
101+
('2001', '1003');
102+
103+
-- R2 Appears in
104+
insert into character_appears_in (character_id, appears_in) values
105+
('2001', 3),
106+
('2001', 4),
107+
('2001', 5),
108+
('2001', 6);
109+

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ protected TypedQuery<?> getQuery(DataFetchingEnvironment environment, Field fiel
136136
// optionally add default ordering
137137
mayBeAddDefaultOrderBy(query, join, cb);
138138

139-
return entityManager.createQuery(query.distinct(true));
139+
return entityManager.createQuery(query.distinct(isDistinct));
140140

141141
}
142142

0 commit comments

Comments
 (0)