通过 REST 控制器使用 Spring Data JPA 和 QueryDsl 的异常

Posted

技术标签:

【中文标题】通过 REST 控制器使用 Spring Data JPA 和 QueryDsl 的异常【英文标题】:Exception using Spring Data JPA and QueryDsl via REST Controller 【发布时间】:2015-12-05 20:29:54 【问题描述】:

我正在尝试实现一种控制器方法,该方法类似于支持 QueryDsl 的最新 Gosling 发布系列的 Spring Data 中记录的方法。我已经实现了控制器,如http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#core.web.type-safe 文档中的示例所示。一切都会编译,当我启动应用程序(使用 Spring Boot 1.2.5.RELEASE)时,一切都开始正常。

但是,当我尝试调用我的休息端点时,我总是得到以下异常:

org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mysema.query.types.Predicate]: Specified class is an interface
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:80)

我的猜测是 QuerydslPredicateArgumentResolver 没有应用于请求,因此是异常。但是当我查询 Spring Boot 管理端点 /manage/beans 时,我看到 QuerydslPredicateArgumentResolver 已注册为 bean。我还确保 @EnableSpringDataWebSupport 在我的 @Configuration 类上无效。

我使用@BasePathAwareController 注释控制器,因为我将它与 Spring Data REST 一起使用,并且我希望这些方法与 Spring Data REST 公开的方法处于类似的路径下。我也尝试过使用@RepositoryRestController,但这似乎并不重要。但是,当使用 @RestController 并将其放在与 Spring Data REST 使用的基本路径不同的路径下时,一切正常。所以问题是,它应该有效吗?

现在整个控制器是:

@RestController
@RequestMapping(value = "/query")
public class AvailController

    private final AvailRepository repo;

    @Autowired
    public AvailController(AvailRepository repository)
    
        this.repo = repository;
    

    @RequestMapping(value = "/avails", method = GET)
    public @ResponseBody Page<Avail> getAvails(Model model, 
               @QuerydslPredicate(root = Avail.class) Predicate predicate,
               Pageable pageable, 
               @RequestParam MultiValueMap<String, String> parameters)
    
        return repo.findAll(predicate, pageable);
    

【问题讨论】:

我得到了它的工作,但使用 XML 配置。也许这可能会有所帮助***.com/questions/32366562/… 手动 Web Mvc 配置也可能导致类似的错误。见***.com/a/62835165/6346531 【参考方案1】:

我在 Predicate 的实例化时遇到了同样的问题。在示例中:

@Controller
@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
class UserController 

private final UserRepository repository;

@RequestMapping(value = "/", method = RequestMethod.GET)
String index(Model model, //
        @QuerydslPredicate(root = User.class) Predicate predicate, //
        @PageableDefault(sort =  "lastname", "firstname" ) Pageable pageable, //
        @RequestParam MultiValueMap<String, String> parameters) 
(...)

(https://github.com/spring-projects/spring-data-examples/blob/master/web/querydsl/src/main/java/example/users/web/UserController.java#L42) 只使用@Controller 而我使用的是@RepositoryRestController,这似乎是原因。 @RestController 也适用于我。

我创建了https://jira.spring.io/browse/DATAREST-838

【讨论】:

提供链接很好,但最好在答案中包含重要部分..!!【参考方案2】:

在尝试实现将返回值模拟为 Spring Data REST 的自定义控制器时,我也遇到了这个问题。我想将 QuerydslPredicate 注入控制器方法并得到烦人的“BeanInstantiationException”。

我通过将以下配置文件添加到我的应用程序中找到了解决此问题的方法:

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE   )
public class MvcConfig extends WebMvcConfigurerAdapter 

    @Autowired
    @Qualifier("repositoryExporterHandlerAdapter")
    RequestMappingHandlerAdapter repositoryExporterHandlerAdapter;

    @Override
    public void addArgumentResolvers(
            List<HandlerMethodArgumentResolver> argumentResolvers) 
        List<HandlerMethodArgumentResolver> customArgumentResolvers = repositoryExporterHandlerAdapter.getCustomArgumentResolvers();
        argumentResolvers.addAll(customArgumentResolvers);
    

参考这里:https://jira.spring.io/browse/DATAREST-657

【讨论】:

以上是关于通过 REST 控制器使用 Spring Data JPA 和 QueryDsl 的异常的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring-Data-Rest 中实现细粒度的访问控制?

我可以让自定义控制器镜像 Spring-Data-Rest / Spring-Hateoas 生成的类的格式吗?

Spring Data Rest 不能做集成测试?

Spring Data REST:覆盖控制器上的存储库方法

Spring Data REST 似乎不适用于 elasticsearch

Spring Data Rest:如何使用请求正文发送多部分文件