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

5
需要翻译的内容:

经过大量挖掘,发现使用Spring-Data-Rest和QueryDSL可以使REST API客户端轻松过滤实体的大多数属性。

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

如Dennis Laumen所提到的,QueryDslPredicateExecutorQuerydslBinderCustomizer提供了一些令人惊叹的功能,但缺乏文档。

我正在尝试解决的具体问题是:

我有一个用户实体,与UserGroup实体具有@ManyToMany映射关系

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,并且试图使用反射在其上找到属性 'name'。但实际上我需要的 query-dsl 路径是 user.userGroups.any().name

然而,在 URL 上尝试任何其他语法似乎都不被识别为有效的 PropertyPath,在 QuerydslPredicateBuilder.getPredicate 中。

这是一个 bug 吗?


这个有什么更新吗? - chrismarx
抱歉,我希望有来自Spring Data团队的人能够澄清。 - gazal
我猜我们可能需要在这里做出贡献:https://github.com/spring-projects/spring-data-jpa - gazal
看起来这是一个 bug - https://jira.spring.io/browse/DATAREST-694 - chrismarx
我认为那个 bug 并没有真正捕捉到我提到的问题,但是修复那个 bug 的解决方案可以有所帮助。我已经点赞了 :) - gazal
1个回答

0
在我的情况下,升级到spring-data Ingalls-SR7解决了这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接