Skip to content

Commit 5d99c3b

Browse files
authored
fix(GH-198): adedd support for fetching optional element collections elements (#200)
* fix: adedd support for fetching optional element collections elements * fix(test): polished queryOptionalElementCollections * polish(test): added tags selection field to queryOptionalElementCollections
1 parent 9854252 commit 5d99c3b

File tree

5 files changed

+80
-9
lines changed

5 files changed

+80
-9
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,16 @@ insert into book (id, title, author_id, genre) values (5, 'The Cherry Orchard',
77
insert into book (id, title, author_id, genre) values (6, 'The Seagull', 4, 'PLAY');
88
insert into book (id, title, author_id, genre) values (7, 'Three Sisters', 4, 'PLAY');
99
insert into author (id, name, genre) values (8, 'Igor Dianov', 'JAVA');
10+
11+
insert into book_tags (book_id, tags) values (2, 'war'), (2, 'piece');
12+
insert into book_tags (book_id, tags) values (3, 'anna'), (3, 'karenina');
13+
insert into book_tags (book_id, tags) values (5, 'cherry'), (5, 'orchard');
14+
insert into book_tags (book_id, tags) values (6, 'seagull');
15+
insert into book_tags (book_id, tags) values (7, 'three'), (7, 'sisters');
16+
17+
insert into author_phone_numbers(phone_number, author_id) values
18+
('1-123-1234', 1),
19+
('1-123-5678', 1),
20+
('4-123-1234', 4),
21+
('4-123-5678', 4);
22+

graphql-jpa-query-example-model-books/src/main/java/com/introproventures/graphql/jpa/query/schema/model/book/Book.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,29 @@
1717
package com.introproventures.graphql.jpa.query.schema.model.book;
1818

1919
import java.util.Date;
20+
import java.util.LinkedHashSet;
21+
import java.util.Set;
2022

21-
import javax.persistence.*;
23+
import javax.persistence.ElementCollection;
24+
import javax.persistence.Entity;
25+
import javax.persistence.EnumType;
26+
import javax.persistence.Enumerated;
27+
import javax.persistence.FetchType;
28+
import javax.persistence.Id;
29+
import javax.persistence.ManyToOne;
30+
import javax.persistence.Transient;
2231

32+
import com.introproventures.graphql.jpa.query.annotation.GraphQLDescription;
2333
import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnore;
2434
import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreFilter;
2535
import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnoreOrder;
36+
2637
import lombok.Data;
2738
import lombok.EqualsAndHashCode;
2839

2940
@Data
3041
@Entity
31-
@EqualsAndHashCode(exclude="author")
42+
@EqualsAndHashCode(exclude= {"author", "tags"})
3243
public class Book {
3344
@Id
3445
Long id;
@@ -38,6 +49,10 @@ public class Book {
3849
@GraphQLIgnoreOrder
3950
@GraphQLIgnoreFilter
4051
String description;
52+
53+
@ElementCollection(fetch = FetchType.LAZY)
54+
@GraphQLDescription("A set of user-defined tags")
55+
private Set<String> tags = new LinkedHashSet<>();
4156

4257
@ManyToOne(fetch=FetchType.LAZY, optional = false)
4358
Author author;

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -218,20 +218,20 @@ protected final List<Predicate> getFieldPredicates(Field field, CriteriaQuery<?>
218218
// Let's do fugly conversion
219219
// the many end is a collection, and it is always optional by default (empty collection)
220220
isOptional = optionalArgument.map(it -> getArgumentValue(environment, it, Boolean.class))
221-
.orElse(toManyDefaultOptional);
221+
.orElse(toManyDefaultOptional);
222222

223-
// Let's apply join to retrieve associated collection
224-
fetch = reuseFetch(from, selectedField.getName(), isOptional);
225-
226-
// Let's fetch element collections to avoid filtering their values used where search criteria
227223
GraphQLObjectType objectType = getObjectType(environment);
228224
EntityType<?> entityType = getEntityType(objectType);
229225

230226
PluralAttribute<?, ?, ?> attribute = (PluralAttribute<?, ?, ?>) entityType.getAttribute(selectedField.getName());
231227

228+
// Let's join fetch element collections to avoid filtering their values used where search criteria
232229
if(PersistentAttributeType.ELEMENT_COLLECTION == attribute.getPersistentAttributeType()) {
233-
from.fetch(selectedField.getName());
234-
}
230+
from.fetch(selectedField.getName(), JoinType.LEFT);
231+
} else {
232+
// Let's apply fetch join to retrieve associated plural attributes
233+
fetch = reuseFetch(from, selectedField.getName(), isOptional);
234+
}
235235
}
236236
// Let's build join fetch graph to avoid Hibernate error:
237237
// "query specified join fetching, but the owner of the fetched association was not present in the select list"

graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,4 +1611,41 @@ public void queryWithEnumParameterShouldExecuteWithNoError() {
16111611
"War and Peace")
16121612
);
16131613
}
1614+
1615+
// https://github.com/introproventures/graphql-jpa-query/issues/198
1616+
@Test
1617+
public void queryOptionalElementCollections() {
1618+
//given
1619+
String query = "{ Author(id: 8) { id name phoneNumbers books { id title tags } } }";
1620+
1621+
String expected = "{Author={id=8, name=Igor Dianov, phoneNumbers=[], books=[]}}";
1622+
1623+
//when
1624+
Object result = executor.execute(query).getData();
1625+
1626+
// then
1627+
assertThat(result.toString()).isEqualTo(expected);
1628+
}
1629+
1630+
@Test
1631+
public void queryElementCollectionsWithWhereCriteriaExpression() {
1632+
//given:
1633+
String query = "query {" +
1634+
" Books(where: {tags: {EQ: \"war\"}}) {" +
1635+
" select {" +
1636+
" id" +
1637+
" title" +
1638+
" tags" +
1639+
" }" +
1640+
" }" +
1641+
"}";
1642+
1643+
String expected = "{Books={select=[{id=2, title=War and Peace, tags=[piece, war]}]}}";
1644+
1645+
//when:
1646+
Object result = executor.execute(query).getData();
1647+
1648+
//then:
1649+
assertThat(result.toString()).isEqualTo(expected);
1650+
}
16141651
}

graphql-jpa-query-schema/src/test/resources/data.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ insert into book (id, title, author_id, genre, publication_date, description)
126126
values (7, 'Three Sisters', 4, 'PLAY', '1900-01-01', 'The play is sometimes included on the short list of Chekhov''s outstanding plays, along with The Cherry Orchard, The Seagull and Uncle Vanya.[1]');
127127
insert into author (id, name, genre) values (8, 'Igor Dianov', 'JAVA');
128128

129+
insert into book_tags (book_id, tags) values (2, 'war'), (2, 'piece');
130+
insert into book_tags (book_id, tags) values (3, 'anna'), (3, 'karenina');
131+
insert into book_tags (book_id, tags) values (5, 'cherry'), (5, 'orchard');
132+
insert into book_tags (book_id, tags) values (6, 'seagull');
133+
insert into book_tags (book_id, tags) values (7, 'three'), (7, 'sisters');
134+
129135
insert into author_phone_numbers(phone_number, author_id) values
130136
('1-123-1234', 1),
131137
('1-123-5678', 1),

0 commit comments

Comments
 (0)