Skip to content

fix(GH-220): Cannot nest multiple queries on the same table #222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import javax.persistence.OrderBy;

import com.introproventures.graphql.jpa.query.annotation.GraphQLDescription;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
Expand All @@ -40,7 +41,7 @@
@Getter
@Setter
@ToString
@EqualsAndHashCode(exclude={"appearsIn","friends"}) // Fixes NPE in Hibernate when initializing loaded collections #1
@EqualsAndHashCode(exclude={"appearsIn","friends", "friendsOf"}) // Fixes NPE in Hibernate when initializing loaded collections #1
public abstract class Character {

@Id
Expand All @@ -58,6 +59,10 @@ public abstract class Character {
@OrderBy("name ASC")
Set<Character> friends;

@ManyToMany(fetch=FetchType.LAZY, mappedBy = "friends")
@OrderBy("name ASC")
Set<Character> friendsOf;

@GraphQLDescription("What Star Wars episodes does this character appear in")
@ElementCollection(targetClass = Episode.class, fetch=FetchType.LAZY)
@Enumerated(EnumType.ORDINAL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ private GraphQLInputObjectType computeSubqueryInputType(ManagedType<?> managedTy
.build()
)
.fields(managedType.getAttributes().stream()
.filter(this::isValidAssociation)
.filter(Attribute::isAssociation)
.filter(this::isNotIgnored)
.filter(this::isNotIgnoredFilter)
.map(this::getWhereInputRelationField)
Expand Down Expand Up @@ -404,7 +404,7 @@ private GraphQLInputObjectType computeWhereInputType(ManagedType<?> managedType)
.collect(Collectors.toList())
)
.fields(managedType.getAttributes().stream()
.filter(this::isValidAssociation)
.filter(Attribute::isAssociation)
.filter(this::isNotIgnored)
.filter(this::isNotIgnoredFilter)
.map(this::getWhereInputRelationField)
Expand Down Expand Up @@ -853,7 +853,9 @@ else if (isElementCollection(attribute)) {
Type foreignType = ((PluralAttribute) attribute).getElementType();

if(foreignType.getPersistenceType() == Type.PersistenceType.BASIC) {
return new GraphQLList(getGraphQLTypeFromJavaType(foreignType.getJavaType()));
GraphQLType graphQLType = getGraphQLTypeFromJavaType(foreignType.getJavaType());

return input ? graphQLType : new GraphQLList(graphQLType);
}
}

Expand Down Expand Up @@ -897,11 +899,6 @@ protected final boolean isValidInput(Attribute<?,?> attribute) {
attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED;
}

protected final boolean isValidAssociation(Attribute<?,?> attribute) {
return isOneToMany(attribute) || isToOne(attribute);
}


private String getSchemaDescription(Attribute<?,?> attribute) {
return EntityIntrospector.introspect(attribute.getDeclaringType())
.getSchemaDescription(attribute.getName())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.metamodel.EntityType;
Expand Down Expand Up @@ -730,27 +730,21 @@ else if(Collection.class.isAssignableFrom(type)) {
// collection join for plural attributes
if(PluralAttribute.class.isInstance(from.getModel())
|| EntityType.class.isInstance(from.getModel())) {
Expression<? extends Collection<Object>> expression = from.get(filter.getField());
Predicate predicate;

if(EntityType.class.isInstance(from.getModel())) {
From<?,?> join = null;

for(Join<?,?> fetch: from.getJoins()) {
if(fetch.getAttribute().getName().equals(filter.getField()))
join = (From<?,?>) fetch;
}
if(Collection.class.isInstance(filter.getValue())) {
List<Predicate> restrictions = new ArrayList<>();

if(join == null) {
join = (From<?,?>) from.join(filter.getField());
}
Collection.class.cast(filter.getValue())
.forEach(v -> restrictions.add(cb.isMember(v, expression)));

predicate = cb.and(restrictions.toArray(new Predicate[] {}));

predicate = join.in(value);
} else {
Expression<? extends Collection<Object>> expression = from.get(filter.getField());

predicate = cb.isMember(filter.getValue(), expression);
}

if(filter.anyMatch(Criteria.NIN, Criteria.NE)) {
return cb.not(predicate);
}
Expand Down
Loading