From ba494bc0036125569e32371c8b4041ca803a0078 Mon Sep 17 00:00:00 2001 From: Ludovic Motte Date: Sat, 29 Dec 2018 13:34:31 +0100 Subject: [PATCH 1/5] EmbeddedId management --- .../schema/impl/GraphQLJpaSchemaBuilder.java | 214 +++++++++++------- .../impl/GraphQLJpaSimpleDataFetcher.java | 33 ++- .../query/schema/GraphQLExecutorTests.java | 10 +- .../jpa/query/schema/model/embedded/Boat.java | 24 +- .../src/test/resources/data.sql | 8 +- 5 files changed, 186 insertions(+), 103 deletions(-) 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 adb48ed29..f2d44e9b1 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 @@ -95,7 +95,8 @@ public class GraphQLJpaSchemaBuilder implements GraphQLSchemaBuilder { private Map, GraphQLType> classCache = new HashMap<>(); private Map, GraphQLObjectType> entityCache = new HashMap<>(); - private Map, GraphQLObjectType> embeddableCache = new HashMap<>(); + private Map, GraphQLObjectType> embeddableOutputCache = new HashMap<>(); + private Map, GraphQLInputObjectType> embeddableInputCache = new HashMap<>(); private static final Logger log = LoggerFactory.getLogger(GraphQLJpaSchemaBuilder.class); @@ -292,13 +293,13 @@ private GraphQLInputType getWhereAttributeType(Attribute attribute) { .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.EQ.name()) .description("Equals criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.NE.name()) .description("Not Equals criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ); @@ -307,25 +308,25 @@ private GraphQLInputType getWhereAttributeType(Attribute attribute) { builder.field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.LE.name()) .description("Less then or Equals criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.GE.name()) .description("Greater or Equals criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.GT.name()) .description("Greater Then criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.LT.name()) .description("Less Then criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ); } @@ -334,25 +335,25 @@ private GraphQLInputType getWhereAttributeType(Attribute attribute) { builder.field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.LIKE.name()) .description("Like criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.CASE.name()) .description("Case sensitive match criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.STARTS.name()) .description("Starts with criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.ENDS.name()) .description("Ends with criteria") - .type((GraphQLInputType) getAttributeType(attribute)) + .type(getAttributeInputType(attribute)) .build() ); } @@ -373,13 +374,13 @@ private GraphQLInputType getWhereAttributeType(Attribute attribute) { .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.IN.name()) .description("In criteria") - .type(new GraphQLList(getAttributeType(attribute))) + .type(new GraphQLList(getAttributeInputType(attribute))) .build() ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.NIN.name()) .description("Not In criteria") - .type(new GraphQLList(getAttributeType(attribute))) + .type(new GraphQLList(getAttributeInputType(attribute))) .build() ) .field(GraphQLInputObjectField.newInputObjectField() @@ -404,39 +405,52 @@ private GraphQLInputType getWhereAttributeType(Attribute attribute) { } private GraphQLArgument getArgument(Attribute attribute) { - GraphQLType type = getAttributeType(attribute); + GraphQLInputType type = getAttributeInputType(attribute); String description = getSchemaDescription(attribute.getJavaMember()); - if (type instanceof GraphQLInputType) { - return GraphQLArgument.newArgument() - .name(attribute.getName()) - .type((GraphQLInputType) type) - .description(description) - .build(); - } - - throw new IllegalArgumentException("Attribute " + attribute + " cannot be mapped as an Input Argument"); + return GraphQLArgument.newArgument() + .name(attribute.getName()) + .type((GraphQLInputType) type) + .description(description) + .build(); } - private GraphQLObjectType getEmbeddableType(EmbeddableType embeddableType) { - if (embeddableCache.containsKey(embeddableType)) - return embeddableCache.get(embeddableType); - - String embeddableTypeName = namingStrategy.singularize(embeddableType.getJavaType().getSimpleName())+"EmbeddableType"; - - GraphQLObjectType objectType = GraphQLObjectType.newObject() - .name(embeddableTypeName) - .description(getSchemaDescription( embeddableType.getJavaType())) - .fields(embeddableType.getAttributes().stream() - .filter(this::isNotIgnored) - .map(this::getObjectField) - .collect(Collectors.toList()) - ) - .build(); - - embeddableCache.putIfAbsent(embeddableType, objectType); + private GraphQLType getEmbeddableType(EmbeddableType embeddableType, boolean input) { + if (input && embeddableInputCache.containsKey(embeddableType)) + return embeddableInputCache.get(embeddableType); + + if (!input && embeddableOutputCache.containsKey(embeddableType)) + return embeddableOutputCache.get(embeddableType); + String embeddableTypeName = namingStrategy.singularize(embeddableType.getJavaType().getSimpleName())+ (input ? "Input" : "") +"EmbeddableType"; + GraphQLType graphQLType=null; + if (input) { + graphQLType = GraphQLInputObjectType.newInputObject() + .name(embeddableTypeName) + .description(getSchemaDescription(embeddableType.getJavaType())) + .fields(embeddableType.getAttributes().stream() + .filter(this::isNotIgnored) + .map(this::getInputObjectField) + .collect(Collectors.toList()) + ) + .build(); + } else { + graphQLType = GraphQLObjectType.newObject() + .name(embeddableTypeName) + .description(getSchemaDescription(embeddableType.getJavaType())) + .fields(embeddableType.getAttributes().stream() + .filter(this::isNotIgnored) + .map(this::getObjectField) + .collect(Collectors.toList()) + ) + .build(); + } + if (input) { + embeddableInputCache.putIfAbsent(embeddableType, (GraphQLInputObjectType) graphQLType); + } else{ + embeddableOutputCache.putIfAbsent(embeddableType, (GraphQLObjectType) graphQLType); + } - return objectType; + return graphQLType; } @@ -462,52 +476,59 @@ private GraphQLObjectType getObjectType(EntityType entityType) { @SuppressWarnings( { "rawtypes", "unchecked" } ) private GraphQLFieldDefinition getObjectField(Attribute attribute) { - GraphQLType type = getAttributeType(attribute); - - if (type instanceof GraphQLOutputType) { - List arguments = new ArrayList<>(); - DataFetcher dataFetcher = PropertyDataFetcher.fetching(attribute.getName()); - - // Only add the orderBy argument for basic attribute types - if (attribute instanceof SingularAttribute - && attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC) { - arguments.add(GraphQLArgument.newArgument() - .name(ORDER_BY_PARAM_NAME) - .description("Specifies field sort direction in the query results.") - .type(orderByDirectionEnum) - .build() - ); - } - - // Get the fields that can be queried on (i.e. Simple Types, no Sub-Objects) - if (attribute instanceof SingularAttribute - && attribute.getPersistentAttributeType() != Attribute.PersistentAttributeType.BASIC) { - ManagedType foreignType = (ManagedType) ((SingularAttribute) attribute).getType(); - - // TODO fix page count query - arguments.add(getWhereArgument(foreignType)); - - } // Get Sub-Objects fields queries via DataFetcher - else if (attribute instanceof PluralAttribute - && (attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.ONE_TO_MANY - || attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.MANY_TO_MANY)) { - EntityType declaringType = (EntityType) ((PluralAttribute) attribute).getDeclaringType(); - EntityType elementType = (EntityType) ((PluralAttribute) attribute).getElementType(); - - arguments.add(getWhereArgument(elementType)); - dataFetcher = new GraphQLJpaOneToManyDataFetcher(entityManager, declaringType, (PluralAttribute) attribute); - } + GraphQLOutputType type = getAttributeOutputType(attribute); + + List arguments = new ArrayList<>(); + DataFetcher dataFetcher = PropertyDataFetcher.fetching(attribute.getName()); + + // Only add the orderBy argument for basic attribute types + if (attribute instanceof SingularAttribute + && attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC) { + arguments.add(GraphQLArgument.newArgument() + .name(ORDER_BY_PARAM_NAME) + .description("Specifies field sort direction in the query results.") + .type(orderByDirectionEnum) + .build() + ); + } - return GraphQLFieldDefinition.newFieldDefinition() - .name(attribute.getName()) - .description(getSchemaDescription(attribute.getJavaMember())) - .type((GraphQLOutputType) type) - .dataFetcher(dataFetcher) - .argument(arguments) - .build(); + // Get the fields that can be queried on (i.e. Simple Types, no Sub-Objects) + if (attribute instanceof SingularAttribute + && attribute.getPersistentAttributeType() != Attribute.PersistentAttributeType.BASIC) { + ManagedType foreignType = (ManagedType) ((SingularAttribute) attribute).getType(); + + // TODO fix page count query + arguments.add(getWhereArgument(foreignType)); + + } // Get Sub-Objects fields queries via DataFetcher + else if (attribute instanceof PluralAttribute + && (attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.ONE_TO_MANY + || attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.MANY_TO_MANY)) { + EntityType declaringType = (EntityType) ((PluralAttribute) attribute).getDeclaringType(); + EntityType elementType = (EntityType) ((PluralAttribute) attribute).getElementType(); + + arguments.add(getWhereArgument(elementType)); + dataFetcher = new GraphQLJpaOneToManyDataFetcher(entityManager, declaringType, (PluralAttribute) attribute); } - throw new IllegalArgumentException("Attribute " + attribute + " cannot be mapped as an Output Argument"); + return GraphQLFieldDefinition.newFieldDefinition() + .name(attribute.getName()) + .description(getSchemaDescription(attribute.getJavaMember())) + .type(type) + .dataFetcher(dataFetcher) + .argument(arguments) + .build(); + } + + @SuppressWarnings( { "rawtypes", "unchecked" } ) + private GraphQLInputObjectField getInputObjectField(Attribute attribute) { + GraphQLInputType type = getAttributeInputType(attribute); + + return GraphQLInputObjectField.newInputObjectField() + .name(attribute.getName()) + .description(getSchemaDescription(attribute.getJavaMember())) + .type(type) + .build(); } private Stream> findBasicAttributes(Collection> attributes) { @@ -515,14 +536,32 @@ private Stream> findBasicAttributes(Collection> at } @SuppressWarnings( "rawtypes" ) - private GraphQLType getAttributeType(Attribute attribute) { + private GraphQLInputType getAttributeInputType(Attribute attribute) { + try{ + return (GraphQLInputType) getAttributeType(attribute, true); + } catch (ClassCastException e){ + throw new IllegalArgumentException("Attribute " + attribute + " cannot be mapped as an Input Argument"); + } + } + + @SuppressWarnings( "rawtypes" ) + private GraphQLOutputType getAttributeOutputType(Attribute attribute) { + try { + return (GraphQLOutputType) getAttributeType(attribute, false); + } catch (ClassCastException e){ + throw new IllegalArgumentException("Attribute " + attribute + " cannot be mapped as an Output Argument"); + } + } + + @SuppressWarnings( "rawtypes" ) + private GraphQLType getAttributeType(Attribute attribute, boolean input) { if (isBasic(attribute)) { return getGraphQLTypeFromJavaType(attribute.getJavaType()); } else if (isEmbeddable(attribute)) { EmbeddableType embeddableType = (EmbeddableType) ((SingularAttribute) attribute).getType(); - return getEmbeddableType(embeddableType); + return getEmbeddableType(embeddableType, input); } else if (isToMany(attribute)) { EntityType foreignType = (EntityType) ((PluralAttribute) attribute).getElementType(); @@ -572,7 +611,8 @@ protected final boolean isToOne(Attribute attribute) { protected final boolean isValidInput(Attribute attribute) { return attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC || - attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION; + attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION || + attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED; } private String getSchemaDescription(Member member) { diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSimpleDataFetcher.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSimpleDataFetcher.java index 1a671fefc..b3445d330 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSimpleDataFetcher.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaSimpleDataFetcher.java @@ -21,9 +21,15 @@ import javax.persistence.NoResultException; import javax.persistence.metamodel.EntityType; +import graphql.language.Argument; import graphql.language.Field; +import graphql.language.ObjectValue; import graphql.schema.DataFetchingEnvironment; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + class GraphQLJpaSimpleDataFetcher extends QraphQLJpaBaseDataFetcher { public GraphQLJpaSimpleDataFetcher(EntityManager entityManager, EntityType entityType) { @@ -32,11 +38,13 @@ public GraphQLJpaSimpleDataFetcher(EntityManager entityManager, EntityType en @Override public Object get(DataFetchingEnvironment environment) { - - Field field = environment.getFields().iterator().next(); + Field field = environment.getFields().iterator().next(); + if(!field.getArguments().isEmpty()) { + flattenEmbeddedIdArguments(field); + try { // Create entity graph from selection EntityGraph entityGraph = buildEntityGraph(field); @@ -52,5 +60,24 @@ public Object get(DataFetchingEnvironment environment) { } return null; - } + } + + private void flattenEmbeddedIdArguments(Field field) { + // manage object arguments (EmbeddedId) + final List argumentsWhereObjectsAreFlattened = field.getArguments() + .stream() + .flatMap(argument -> + { + if (!argument.getName().equals("where") && !argument.getName().equals("page") && + argument.getValue() instanceof ObjectValue) { + return ((ObjectValue) argument.getValue()).getObjectFields() + .stream() + .map(objectField -> new Argument(argument.getName() + "." + objectField.getName(), objectField.getValue())); + } else { + return Stream.of(argument); + } + }) + .collect(Collectors.toList()); + field.setArguments(argumentsWhereObjectsAreFlattened); + } } 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 7732c8def..52271d024 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 @@ -364,9 +364,9 @@ public void queryForEntityWithMappedSuperclass() { @Test public void queryForEntityWithEmeddableType() { //given - String query = "{ Boat(id: \"1\") { id engine { identification } } }"; + String query = "{ Boat(boatId: {id: \"1\" country: \"EN\"}) { boatId {id country} engine { identification } } }"; - String expected = "{Boat={id=1, engine={identification=12345}}}"; + String expected = "{Boat={boatId={id=1, country=EN}, engine={identification=12345}}}"; //when Object result = executor.execute(query).getData(); @@ -378,9 +378,9 @@ public void queryForEntityWithEmeddableType() { @Test public void queryForEntityWithEmeddableTypeAndWhere() { //given - String query = "{ Boats { select { id engine(where: { identification: { EQ: \"12345\"}}) { identification } } } }"; + String query = "{ Boats { select { boatId {id country} engine(where: { identification: { EQ: \"12345\"}}) { identification } } } }"; - String expected = "{Boats={select=[{id=1, engine={identification=12345}}]}}"; + String expected = "{Boats={select=[{boatId={id=1, country=EN}, engine={identification=12345}}]}}"; //when Object result = executor.execute(query).getData(); @@ -460,4 +460,6 @@ public void queryWithDateNotBetweenPredicate() { } + + } \ No newline at end of file diff --git a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/model/embedded/Boat.java b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/model/embedded/Boat.java index 9d356fd44..6cd3eeeb2 100644 --- a/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/model/embedded/Boat.java +++ b/graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/model/embedded/Boat.java @@ -1,19 +1,33 @@ package com.introproventures.graphql.jpa.query.schema.model.embedded; +import com.introproventures.graphql.jpa.query.annotation.GraphQLDescription; +import lombok.Data; + +import javax.persistence.Embeddable; import javax.persistence.Embedded; +import javax.persistence.EmbeddedId; import javax.persistence.Entity; -import javax.persistence.Id; - -import lombok.Data; +import java.io.Serializable; @Entity(name = "Boat") @Data public class Boat { - @Id - String id; + @Embeddable + @Data + public static class BoatId implements Serializable { + private static final long serialVersionUID = 1L; + + String id; + String country; + } + + @EmbeddedId + @GraphQLDescription("Primary Key for the Boat Class") + BoatId boatId; @Embedded Engine engine; + } diff --git a/graphql-jpa-query-schema/src/test/resources/data.sql b/graphql-jpa-query-schema/src/test/resources/data.sql index 85c811ae3..30ddb158b 100644 --- a/graphql-jpa-query-schema/src/test/resources/data.sql +++ b/graphql-jpa-query-schema/src/test/resources/data.sql @@ -129,8 +129,8 @@ insert into Car (id, brand) values -- Boat -insert into Boat (id, identification) values - (1, '12345'), - (2, '23456'), - (3, '34567'); +insert into Boat (id, country, identification) values + (1, 'EN', '12345'), + (2, 'EN', '23456'), + (1, 'FR', '34567'); \ No newline at end of file From 8a155e4085bf167a3ab62d09370e30ad3a999877 Mon Sep 17 00:00:00 2001 From: Igor Dianov Date: Fri, 25 Jan 2019 13:42:33 -0800 Subject: [PATCH 2/5] todo: fix failing test for plural query with embeddable id criteria. --- .../jpa/query/schema/GraphQLExecutorTests.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 52271d024..2f5cd5387 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 @@ -460,6 +460,18 @@ public void queryWithDateNotBetweenPredicate() { } + @Test + public void queryForEntitiesWithEmeddableTypeAndWhereEmbeddableId() { + //given + String query = "{ Boats(where: {boatId: {EQ: {id: \"1\" country: \"EN\"}}}) { select { boatId {id country} engine { identification } } } }"; + String expected = "{Boats={select=[{boatId={id=1, country=EN}, engine={identification=12345}}]}}"; + + //when + Object result = executor.execute(query).getData(); + // then + assertThat(result.toString()).isEqualTo(expected); + } + } \ No newline at end of file From ec7becb708cde43d1bb539be3a5c9d381a570928 Mon Sep 17 00:00:00 2001 From: Ludovic Motte Date: Sun, 3 Feb 2019 14:38:49 +0100 Subject: [PATCH 3/5] fix test : @EmbeddedId share same where syntax than @Embedded --- .../graphql/jpa/query/schema/GraphQLExecutorTests.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 2f5cd5387..8a58bd0ca 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 @@ -362,7 +362,7 @@ public void queryForEntityWithMappedSuperclass() { // https://github.com/introproventures/graphql-jpa-query/issues/30 @Test - public void queryForEntityWithEmeddableType() { + public void queryForEntityWithEmbeddedIdAndEmbeddedField() { //given String query = "{ Boat(boatId: {id: \"1\" country: \"EN\"}) { boatId {id country} engine { identification } } }"; @@ -376,7 +376,7 @@ public void queryForEntityWithEmeddableType() { } @Test - public void queryForEntityWithEmeddableTypeAndWhere() { + public void queryForEntityWithEmbeddedFieldWithWhere() { //given String query = "{ Boats { select { boatId {id country} engine(where: { identification: { EQ: \"12345\"}}) { identification } } } }"; @@ -461,9 +461,9 @@ public void queryWithDateNotBetweenPredicate() { @Test - public void queryForEntitiesWithEmeddableTypeAndWhereEmbeddableId() { + public void queryForEntitiesWithWithEmbeddedIdWithWhere() { //given - String query = "{ Boats(where: {boatId: {EQ: {id: \"1\" country: \"EN\"}}}) { select { boatId {id country} engine { identification } } } }"; + String query = "{ Boats { select { boatId(where: { AND: {id: { LIKE: \"1\"} country: { EQ: \"EN\"}}}) {id country} engine { identification } } } }"; String expected = "{Boats={select=[{boatId={id=1, country=EN}, engine={identification=12345}}]}}"; @@ -473,5 +473,5 @@ public void queryForEntitiesWithEmeddableTypeAndWhereEmbeddableId() { // then assertThat(result.toString()).isEqualTo(expected); } - + } \ No newline at end of file From 789318120967699a59d7c02bb6a1342cdff0a53f Mon Sep 17 00:00:00 2001 From: Ludovic Motte Date: Sun, 10 Feb 2019 18:17:19 +0100 Subject: [PATCH 4/5] test : remove explicit AND as it is implicit by default --- .../graphql/jpa/query/schema/GraphQLExecutorTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8a58bd0ca..c1e97465a 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 @@ -463,7 +463,7 @@ public void queryWithDateNotBetweenPredicate() { @Test public void queryForEntitiesWithWithEmbeddedIdWithWhere() { //given - String query = "{ Boats { select { boatId(where: { AND: {id: { LIKE: \"1\"} country: { EQ: \"EN\"}}}) {id country} engine { identification } } } }"; + String query = "{ Boats { select { boatId(where: { id: { LIKE: \"1\"} country: { EQ: \"EN\"}}) {id country} engine { identification } } } }"; String expected = "{Boats={select=[{boatId={id=1, country=EN}, engine={identification=12345}}]}}"; From 282b4861ca74f5777ed4b163a81334ae32c65263 Mon Sep 17 00:00:00 2001 From: Igor Dianov Date: Mon, 4 Mar 2019 12:08:19 -0800 Subject: [PATCH 5/5] fix: use getAttributeInputType method --- .../jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 f2d44e9b1..e08e3fbd6 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 @@ -42,12 +42,16 @@ import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.Type; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.introproventures.graphql.jpa.query.annotation.GraphQLDescription; import com.introproventures.graphql.jpa.query.annotation.GraphQLIgnore; import com.introproventures.graphql.jpa.query.schema.GraphQLSchemaBuilder; import com.introproventures.graphql.jpa.query.schema.JavaScalars; import com.introproventures.graphql.jpa.query.schema.NamingStrategy; import com.introproventures.graphql.jpa.query.schema.impl.PredicateFilter.Criteria; + import graphql.Assert; import graphql.Scalars; import graphql.schema.Coercing; @@ -65,8 +69,6 @@ import graphql.schema.GraphQLType; import graphql.schema.GraphQLTypeReference; import graphql.schema.PropertyDataFetcher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * JPA specific schema builder implementation of {code #GraphQLSchemaBuilder} interface @@ -386,13 +388,13 @@ private GraphQLInputType getWhereAttributeType(Attribute attribute) { .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.BETWEEN.name()) .description("Between criteria") - .type(new GraphQLList(getAttributeType(attribute))) + .type(new GraphQLList(getAttributeInputType(attribute))) .build() ) .field(GraphQLInputObjectField.newInputObjectField() .name(Criteria.NOT_BETWEEN.name()) .description("Not Between criteria") - .type(new GraphQLList(getAttributeType(attribute))) + .type(new GraphQLList(getAttributeInputType(attribute))) .build() );