From 97faaeb546406d8f1dab5a617b12d8e3b90785d6 Mon Sep 17 00:00:00 2001 From: Igor Dianov Date: Sun, 17 May 2020 12:35:47 -0700 Subject: [PATCH 1/2] fix: Resolve query fetch result in memory to avoid N+1 query problems --- .../jpa/query/schema/impl/GraphQLJpaQueryFactory.java | 4 ++-- .../query/schema/impl/GraphQLJpaToOneDataFetcher.java | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) 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 a5220a99d..31e288558 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 @@ -227,8 +227,8 @@ protected Stream getResultStream(TypedQuery query, } // Let's execute query and get wrap result into stream - return query.getResultStream() - .peek(entityManager::detach); + return query.getResultList() + .stream(); } protected Object querySingleResult(final DataFetchingEnvironment environment) { diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaToOneDataFetcher.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaToOneDataFetcher.java index ded77cbc6..f9d95f6b5 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaToOneDataFetcher.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaToOneDataFetcher.java @@ -16,9 +16,10 @@ package com.introproventures.graphql.jpa.query.schema.impl; +import static javax.persistence.metamodel.Attribute.PersistentAttributeType.EMBEDDED; + import java.util.Optional; -import javax.persistence.metamodel.Attribute.PersistentAttributeType; import javax.persistence.metamodel.SingularAttribute; import org.dataloader.DataLoader; @@ -27,6 +28,7 @@ import org.dataloader.MappedBatchLoaderWithContext; import graphql.GraphQLContext; +import graphql.language.Argument; import graphql.language.Field; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; @@ -55,11 +57,10 @@ public Object get(DataFetchingEnvironment environment) { GraphQLType parentType = environment.getParentType(); Object source = environment.getSource(); - Boolean isOptional = queryFactory.getOptionalArgumentValue(environment, - field, - attribute); + Optional whereArgument = queryFactory.getArgument(field, "where"); + // Resolve collection query if where argument is present - if (isOptional && !PersistentAttributeType.EMBEDDED.equals(attribute.getPersistentAttributeType())) { + if (whereArgument.isPresent() && !EMBEDDED.equals(attribute.getPersistentAttributeType())) { Object parentIdValue = queryFactory.getParentIdAttributeValue(source); String dataLoaderKey = parentType.getName() + "." + Optional.ofNullable(field.getAlias()) .orElseGet(attribute::getName); From 917522a79f6a880dc491536318c2ea0d54200c8e Mon Sep 17 00:00:00 2001 From: Igor Dianov Date: Sun, 17 May 2020 13:19:59 -0700 Subject: [PATCH 2/2] fix: optimize to one dala loader query --- .../jpa/query/schema/impl/GraphQLJpaToOneDataFetcher.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaToOneDataFetcher.java b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaToOneDataFetcher.java index f9d95f6b5..08e197f2b 100644 --- a/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaToOneDataFetcher.java +++ b/graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaToOneDataFetcher.java @@ -58,9 +58,11 @@ public Object get(DataFetchingEnvironment environment) { Object source = environment.getSource(); Optional whereArgument = queryFactory.getArgument(field, "where"); - + Boolean isOptional = queryFactory.getOptionalArgumentValue(environment, + field, + attribute); // Resolve collection query if where argument is present - if (whereArgument.isPresent() && !EMBEDDED.equals(attribute.getPersistentAttributeType())) { + if ((whereArgument.isPresent() && isOptional) && !EMBEDDED.equals(attribute.getPersistentAttributeType())) { Object parentIdValue = queryFactory.getParentIdAttributeValue(source); String dataLoaderKey = parentType.getName() + "." + Optional.ofNullable(field.getAlias()) .orElseGet(attribute::getName);