diff --git a/graphql-jpa-query-example-model-books/src/main/java/com/introproventures/graphql/jpa/query/schema/model/book/Book.java b/graphql-jpa-query-example-model-books/src/main/java/com/introproventures/graphql/jpa/query/schema/model/book/Book.java index bd09878bb..b9df8e1f8 100644 --- a/graphql-jpa-query-example-model-books/src/main/java/com/introproventures/graphql/jpa/query/schema/model/book/Book.java +++ b/graphql-jpa-query-example-model-books/src/main/java/com/introproventures/graphql/jpa/query/schema/model/book/Book.java @@ -39,7 +39,7 @@ @Data @Entity -@EqualsAndHashCode(exclude= {"author", "tags"}) +@EqualsAndHashCode(exclude= {"author", "tags", "publishers"}) public class Book { @Id Long id; @@ -64,6 +64,9 @@ public class Book { Genre genre; Date publicationDate; + + @ElementCollection(fetch = FetchType.LAZY) + Set publishers; @Transient @GraphQLIgnore diff --git a/graphql-jpa-query-example-model-books/src/main/java/com/introproventures/graphql/jpa/query/schema/model/book/Publisher.java b/graphql-jpa-query-example-model-books/src/main/java/com/introproventures/graphql/jpa/query/schema/model/book/Publisher.java new file mode 100644 index 000000000..3fd42c604 --- /dev/null +++ b/graphql-jpa-query-example-model-books/src/main/java/com/introproventures/graphql/jpa/query/schema/model/book/Publisher.java @@ -0,0 +1,13 @@ +package com.introproventures.graphql.jpa.query.schema.model.book; + +import javax.persistence.Embeddable; + +import lombok.Data; + +@Data +@Embeddable +public class Publisher { + private String name; + + private String country; +} diff --git a/graphql-jpa-query-example-relay/src/main/resources/data.sql b/graphql-jpa-query-example-relay/src/main/resources/data.sql index b084133fb..2bb5d051c 100644 --- a/graphql-jpa-query-example-relay/src/main/resources/data.sql +++ b/graphql-jpa-query-example-relay/src/main/resources/data.sql @@ -24,3 +24,7 @@ insert into author_phone_numbers(phone_number, author_id) values ('1-123-5678', 1), ('4-123-1234', 4), ('4-123-5678', 4); + +insert into book_publishers(book_id, name, country) values + (3, 'Independent', 'UK'), (3, 'Amazon', 'US'), + (2, 'Willey', 'US'), (2, 'Simon', 'EU'); diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryFactory.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryFactory.java index 31e288558..5f69b40c8 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryFactory.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryFactory.java @@ -866,6 +866,7 @@ protected Predicate getObjectFieldPredicate(DataFetchingEnvironment environment, if(isEntityType(environment)) { Attribute attribute = getAttribute(environment, argument.getName()); + // TODO add support for embedded element collection, i.e. attribute.isCollection() if(attribute.isAssociation()) { GraphQLFieldDefinition fieldDefinition = getFieldDefinition(environment.getGraphQLSchema(), this.getObjectType(environment), diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java index 53fbb6932..75af0c9d1 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java @@ -58,6 +58,7 @@ import com.introproventures.graphql.jpa.query.schema.impl.EntityIntrospector.EntityIntrospectionResult.AttributePropertyDescriptor; import com.introproventures.graphql.jpa.query.schema.impl.PredicateFilter.Criteria; import com.introproventures.graphql.jpa.query.schema.relay.GraphQLJpaRelayDataFetcher; + import graphql.Assert; import graphql.Directives; import graphql.Scalars; @@ -418,6 +419,14 @@ private GraphQLArgument computeWhereArgument(ManagedType managedType) { .map(this::getInputObjectField) .collect(Collectors.toList()) ) + // TODO support embedded element collections +// .fields(managedType.getAttributes().stream() +// .filter(Attribute::isCollection) +// .filter(this::isNotIgnored) +// .filter(this::isNotIgnoredFilter) +// .map(this::getInputObjectField) +// .collect(Collectors.toList()) +// ) .build(); return GraphQLArgument.newArgument() @@ -1047,6 +1056,13 @@ else if (isElementCollection(attribute)) { return input ? graphQLType : new GraphQLList(graphQLType); } + else if (foreignType.getPersistenceType() == Type.PersistenceType.EMBEDDABLE) { + EmbeddableType embeddableType = EmbeddableType.class.cast(foreignType); + GraphQLType graphQLType = getEmbeddableType(embeddableType, + input); + + return input ? graphQLType : new GraphQLList(graphQLType); + } } final String declaringType = attribute.getDeclaringType().getJavaType().getName(); // fully qualified name of the entity class diff --git a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java index b2f621ec7..58c6c2e89 100644 --- a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java +++ b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/GraphQLExecutorTests.java @@ -42,6 +42,7 @@ import com.introproventures.graphql.jpa.query.AbstractSpringBootTestSupport; import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaExecutor; import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaSchemaBuilder; + import graphql.ErrorType; import graphql.ExecutionResult; import graphql.GraphQLError; @@ -662,6 +663,30 @@ public void queryForEntityWithEmbeddedFieldWithWhere() { // then assertThat(result.toString()).isEqualTo(expected); } + + @Test + public void queryForEntityWithEmbeddableElementCollection() { + //given + String query = "{ Books(where: { author: {name: {LIKE: \"Leo\"}}}) { select { id title publishers { name country } } } }"; + + String expected = "{Books={select=[" + + "{id=2, title=War and Peace, publishers=[" + + "{name=Willey, country=US}, " + + "{name=Simon, country=EU}" + + "]}, " + + "{id=3, title=Anna Karenina, publishers=[" + + "{name=Independent, country=UK}, " + + "{name=Amazon, country=US}" + + "]}" + + "]}}"; + + //when + Object result = executor.execute(query).getData(); + + // then + assertThat(result.toString()).isEqualTo(expected); + } + @Test public void queryWithNumericBetweenPredicate() { diff --git a/graphql-jpa-query-schema/src/test/resources/data.sql b/graphql-jpa-query-schema/src/test/resources/data.sql index 4d32f5b5c..1af705250 100644 --- a/graphql-jpa-query-schema/src/test/resources/data.sql +++ b/graphql-jpa-query-schema/src/test/resources/data.sql @@ -137,6 +137,10 @@ insert into author_phone_numbers(phone_number, author_id) values ('1-123-5678', 1), ('4-123-1234', 4), ('4-123-5678', 4); + +insert into book_publishers(book_id, name, country) values + (3, 'Independent', 'UK'), (3, 'Amazon', 'US'), + (2, 'Willey', 'US'), (2, 'Simon', 'EU'); -- Car insert into Car (id, brand, identification) values