Spring Data REST 的 QueryDSL 集成,用于查询实体中集合映射的子属性

标签 spring spring-data spring-data-jpa spring-data-rest querydsl

进行了一些主要的挖掘,发现带有 query-dsl 的 spring-data-rest 允许 REST API 客户端轻松过滤实体的大多数属性。

这个问题也很有用:
Can Spring Data REST's QueryDSL integration be used to perform more complex queries?

正如 Dennis Laumen 已经提到的,QueryDslPredicateExecutorQuerydslBinderCustomizer提供一些壮观的功能,但缺乏文档。

我试图破解的具体功能是:

我有一个 User 实体,@ManyToMany 映射到 UserGroup 实体

public class User {

    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "user_name")
    private String username;

    @ManyToMany
    @JoinTable(name = "fs_user_group_map", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "group_id") })
    private List<UserGroup> userGroups;
}

我正在尝试获取所有用户的用户组名称之一应与文本匹配:

所以我试图点击的 URI 是:/users?userGroups.name=Admin
但这会出错。
19:08:04.423|ERROR|o.s.d.r.w.RepositoryRestExceptionHandler|null
    java.lang.NullPointerException: null
    at org.springframework.util.ReflectionUtils.getField(ReflectionUtils.java:143) ~[spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.reifyPath(QuerydslPredicateBuilder.java:185) ~[spring-data-commons-1.11.2.RELEASE.jar:na]
    at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.reifyPath(QuerydslPredicateBuilder.java:188) ~[spring-data-commons-1.11.2.RELEASE.jar:na]
    at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.getPath(QuerydslPredicateBuilder.java:167) ~[spring-data-commons-1.11.2.RELEASE.jar:na]
    at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.invokeBinding(QuerydslPredicateBuilder.java:136) ~[spring-data-commons-1.11.2.RELEASE.jar:na]
    at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.getPredicate(QuerydslPredicateBuilder.java:111) ~[spring-data-commons-1.11.2.RELEASE.jar:na]
    at org.springframework.data.rest.webmvc.config.QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver.postProcess(QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver.java:91) ~[spring-data-rest-webmvc-2.4.2.RELEASE.jar:na]
    at org.springframework.data.rest.webmvc.config.RootResourceInformationHandlerMethodArgumentResolver.resolveArgument(RootResourceInformationHandlerMethodArgumentResolver.java:92) ~[spring-data-rest-webmvc-2.4.2.RELEASE.jar:na]
    at org.springframework.data.rest.webmvc.config.RootResourceInformationHandlerMethodArgumentResolver.resolveArgument(RootResourceInformationHandlerMethodArgumentResolver.java:40) ~[spring-data-rest-webmvc-2.4.2.RELEASE.jar:na]
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:78) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:860) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [javax.servlet-api-3.1.0.jar:3.1.0]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812) [jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]

围绕 QuerydslPredicateBuilder.reifyPath 的一些调试让我明白 userGroups 是一个 ListPath并且尝试使用反射来查找其上的属性“名称”。但我实际需要的查询 dsl 路径是 user.userGroups.any().name
在 URL 上尝试任何其他语法似乎不被认为是有效的 PropertyPathQuerydslPredicateBuilder.getPredicate .

这是一个错误吗?

最佳答案

就我而言,升级到 spring-data Ingalls-SR7 解决了这个问题。

关于Spring Data REST 的 QueryDSL 集成,用于查询实体中集合映射的子属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35181167/

相关文章:

java - 如果包含在 log.isDebugEnabled() 下,slf4j 记录器不会在 springboot 的控制台中打印日志

java - 在类路径中包含 Qclass

java - 在 Spring java 配置中启用 CrudRepository

java - 如何使用 JPA 2 和 QueryDSL 高效地获取数千条数据库记录?

java - 具有 SqlResultSetMapping 和 native 查询的 JPA 数据存储库

spring-data-jpa - JPA 入站 channel 适配器的示例 Spring 集成 DSL

java - 访问当前用户,在 spring Controller 中,getAuthentication() 返回 null

angularjs - 嵌套 REST 资源的 Angular ui-router 状态名称

java - 使用AlwaysUseFullPath 属性了解使用DispatcherServlet 的URL 映射

spring-data - 如何缩短 Spring Data JPA Repositories 中查询方法的名称?