Skip to content

Commit 04e07c3

Browse files
authored
fix(GH-38): Support JPA @ElementCollection annotation with @embeddable generic type (#270)
1 parent e40e94f commit 04e07c3

File tree

7 files changed

+67
-1
lines changed

7 files changed

+67
-1
lines changed

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
@Data
4141
@Entity
42-
@EqualsAndHashCode(exclude= {"author", "tags"})
42+
@EqualsAndHashCode(exclude= {"author", "tags", "publishers"})
4343
public class Book {
4444
@Id
4545
Long id;
@@ -64,6 +64,9 @@ public class Book {
6464
Genre genre;
6565

6666
Date publicationDate;
67+
68+
@ElementCollection(fetch = FetchType.LAZY)
69+
Set<Publisher> publishers;
6770

6871
@Transient
6972
@GraphQLIgnore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.introproventures.graphql.jpa.query.schema.model.book;
2+
3+
import javax.persistence.Embeddable;
4+
5+
import lombok.Data;
6+
7+
@Data
8+
@Embeddable
9+
public class Publisher {
10+
private String name;
11+
12+
private String country;
13+
}

graphql-jpa-query-example-relay/src/main/resources/data.sql

+4
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ insert into author_phone_numbers(phone_number, author_id) values
2424
('1-123-5678', 1),
2525
('4-123-1234', 4),
2626
('4-123-5678', 4);
27+
28+
insert into book_publishers(book_id, name, country) values
29+
(3, 'Independent', 'UK'), (3, 'Amazon', 'US'),
30+
(2, 'Willey', 'US'), (2, 'Simon', 'EU');

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

+1
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,7 @@ protected Predicate getObjectFieldPredicate(DataFetchingEnvironment environment,
866866
if(isEntityType(environment)) {
867867
Attribute<?,?> attribute = getAttribute(environment, argument.getName());
868868

869+
// TODO add support for embedded element collection, i.e. attribute.isCollection()
869870
if(attribute.isAssociation()) {
870871
GraphQLFieldDefinition fieldDefinition = getFieldDefinition(environment.getGraphQLSchema(),
871872
this.getObjectType(environment),

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

+16
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import com.introproventures.graphql.jpa.query.schema.impl.EntityIntrospector.EntityIntrospectionResult.AttributePropertyDescriptor;
5959
import com.introproventures.graphql.jpa.query.schema.impl.PredicateFilter.Criteria;
6060
import com.introproventures.graphql.jpa.query.schema.relay.GraphQLJpaRelayDataFetcher;
61+
6162
import graphql.Assert;
6263
import graphql.Directives;
6364
import graphql.Scalars;
@@ -418,6 +419,14 @@ private GraphQLArgument computeWhereArgument(ManagedType<?> managedType) {
418419
.map(this::getInputObjectField)
419420
.collect(Collectors.toList())
420421
)
422+
// TODO support embedded element collections
423+
// .fields(managedType.getAttributes().stream()
424+
// .filter(Attribute::isCollection)
425+
// .filter(this::isNotIgnored)
426+
// .filter(this::isNotIgnoredFilter)
427+
// .map(this::getInputObjectField)
428+
// .collect(Collectors.toList())
429+
// )
421430
.build();
422431

423432
return GraphQLArgument.newArgument()
@@ -1047,6 +1056,13 @@ else if (isElementCollection(attribute)) {
10471056

10481057
return input ? graphQLType : new GraphQLList(graphQLType);
10491058
}
1059+
else if (foreignType.getPersistenceType() == Type.PersistenceType.EMBEDDABLE) {
1060+
EmbeddableType embeddableType = EmbeddableType.class.cast(foreignType);
1061+
GraphQLType graphQLType = getEmbeddableType(embeddableType,
1062+
input);
1063+
1064+
return input ? graphQLType : new GraphQLList(graphQLType);
1065+
}
10501066
}
10511067

10521068
final String declaringType = attribute.getDeclaringType().getJavaType().getName(); // fully qualified name of the entity class

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

+25
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import com.introproventures.graphql.jpa.query.AbstractSpringBootTestSupport;
4343
import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaExecutor;
4444
import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaSchemaBuilder;
45+
4546
import graphql.ErrorType;
4647
import graphql.ExecutionResult;
4748
import graphql.GraphQLError;
@@ -662,6 +663,30 @@ public void queryForEntityWithEmbeddedFieldWithWhere() {
662663
// then
663664
assertThat(result.toString()).isEqualTo(expected);
664665
}
666+
667+
@Test
668+
public void queryForEntityWithEmbeddableElementCollection() {
669+
//given
670+
String query = "{ Books(where: { author: {name: {LIKE: \"Leo\"}}}) { select { id title publishers { name country } } } }";
671+
672+
String expected = "{Books={select=["
673+
+ "{id=2, title=War and Peace, publishers=["
674+
+ "{name=Willey, country=US}, "
675+
+ "{name=Simon, country=EU}"
676+
+ "]}, "
677+
+ "{id=3, title=Anna Karenina, publishers=["
678+
+ "{name=Independent, country=UK}, "
679+
+ "{name=Amazon, country=US}"
680+
+ "]}"
681+
+ "]}}";
682+
683+
//when
684+
Object result = executor.execute(query).getData();
685+
686+
// then
687+
assertThat(result.toString()).isEqualTo(expected);
688+
}
689+
665690

666691
@Test
667692
public void queryWithNumericBetweenPredicate() {

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

+4
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ insert into author_phone_numbers(phone_number, author_id) values
137137
('1-123-5678', 1),
138138
('4-123-1234', 4),
139139
('4-123-5678', 4);
140+
141+
insert into book_publishers(book_id, name, country) values
142+
(3, 'Independent', 'UK'), (3, 'Amazon', 'US'),
143+
(2, 'Willey', 'US'), (2, 'Simon', 'EU');
140144

141145
-- Car
142146
insert into Car (id, brand, identification) values

0 commit comments

Comments
 (0)