0

Assumed that I have 2 entity. The first entity is parent of the second entity with one-to-many relation.

class Item {
    String name;
    Integer price;
}

class Order {
    List<Item> items;
    String customerName;
}

And I have repository defined like this:

interface OrderRepository extends JpaRepository<Order, Long>, QueryDslPredicateExecutor<Order> {
}

After that, I have a controller that automatically bind parameter to predicate like this:

@RestController
@RequestMapping(path = "/orders")
class OrderController {
    @RequestMapping(method = RequestMethod.GET)
    List<Order> list(@QuerydslPredicate Predicate predicate) {
        return orderRepository.findAll(predicate);
    }   
}

So, I can query order from repository with a specific filter like this: curl -XGET http://localhost/orders?customerName=John

The problem is that I cannot filter value inside a list. I also try http://localhost/orders?items.name=Bag but got NullPointerException

java.lang.NullPointerException
    at org.springframework.util.ReflectionUtils.getField(ReflectionUtils.java:143) ~[spring-core-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.reifyPath(QuerydslPredicateBuilder.java:185) ~[spring-data-commons-1.11.4.RELEASE.jar:?]
    ...

So, the questions is, how can I filter value inside list with Spring JPA and Querydsl.

Note: I use spring boot 1.3.4 with querydsl-jpa 3.7.4

Thanks.

2
  • 1
    Have you tried to tweak the binding through the means described in the reference documentation, QuerydslBinderCustomizer in particular? Commented Jul 13, 2016 at 9:28
  • @OliverGierke I tried to add custom binding but it also fail. I think the problem is around QuerydslPredicateBuilder#reifyPath which is it tries to access path of item.name but the field of ListPath<QItem> don't have field name that cause NullPointerException. I'm also trying to implement it myself, but my knowledge to code base is very little. Any help would be appreciated. Commented Jul 15, 2016 at 6:44

1 Answer 1

1

That's a two-fold bug actually. Our translation to dot-names is broken for that particular scenario, even if you defined a custom binding like this:

bindings.bind(user.addresses.any().street).as("alias").first(…);

which would be a solution to work around our failure to handle the collection path traversal out of the box.

I've filed DATACMNS-883 for you to solve both problems:

  1. Collection path traversals should automatically result in the call to any() added during path reification.
  2. Manually declared (and aliased) path bindings including an any() traversal should work properly.

Fix is available (try the latest snapshots) and scheduled for both the Ingalls milestone and a Hopper and Gosling service release.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.