Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 对QueryDsl的Spring数据Web支持在应用程序启动时偶尔工作;不总是调用自定义程序_Spring Boot_Spring Data Jpa_Querydsl - Fatal编程技术网

Spring boot 对QueryDsl的Spring数据Web支持在应用程序启动时偶尔工作;不总是调用自定义程序

Spring boot 对QueryDsl的Spring数据Web支持在应用程序启动时偶尔工作;不总是调用自定义程序,spring-boot,spring-data-jpa,querydsl,Spring Boot,Spring Data Jpa,Querydsl,我的项目使用Spring Boot 2.1.3,Java 8,QueryDsl 4.2.1.(这是一个成熟的关键项目,目前无法将SB版本升级到最新的2.4.4。) 最近,我添加了Spring数据web支持,以简化在Spring数据JPA存储库方法中使用的QueryDsl搜索谓词的绑定请求查询参数,并在web控制器方法中添加了@QueryDsl谓词注释。有了为特定属性或整个属性类定制绑定的能力,这似乎非常有效。。。直到我们发现搜索会随机停止工作 经过一些调查,我注意到,有时候,在应用程序启动后,在

我的项目使用Spring Boot 2.1.3Java 8QueryDsl 4.2.1.(这是一个成熟的关键项目,目前无法将SB版本升级到最新的2.4.4。)

最近,我添加了Spring数据web支持,以简化在Spring数据JPA存储库方法中使用的QueryDsl搜索谓词的绑定请求查询参数,并在web控制器方法中添加了
@QueryDsl谓词
注释。有了为特定属性或整个属性类定制绑定的能力,这似乎非常有效。。。直到我们发现搜索会随机停止工作

经过一些调查,我注意到,有时候,在应用程序启动后,在调用需要填充谓词的控制器方法之前,框架不会调用Spring Data JPA存储库上的
customize
方法实现。如果查询有任何依赖自定义绑定的搜索参数,则查询将失败。但这是疯狂的部分我将停止并重新启动应用程序(不做任何更改!),然后一切都将开始工作,相同的查询将产生预期的结果

值得注意的是,在调试模式下重新启动(在IntelliJ IDEA中)似乎可以正确加载所有内容(大多数情况下,但我认为并不总是如此),并且“定制”方法中的代码将得到执行。我会多次停止并重新启动应用程序,而不进行任何更改或重建。有时它会工作,有时它不会!相同的查询/请求。在不同的环境中,行为的不一致性是相同的。我已经确保QueryDSL APT依赖项(用于Q类型的注释处理和代码生成)是使用提供的作用域
声明的,而不是打包到JAR中

我看到Spring QueryDsl库始终包含在类路径中,并且在类路径中可用,这应该确保根据文档自动启用对
@QueryDsl谓词
注释的支持。根据启动时的随机情况,框架似乎找不到所需域类型(我的实体类)的定制器实现

一旦它起作用,它就起作用了。但我永远无法确定一旦应用程序停止并重新启动,它是否会被启用。有人知道是什么可能导致这种奇怪的行为吗?也许是版本不匹配?对QueryDsl的Spring数据Web支持中的一个bug?我是否应该尝试使用不同的、早期版本的SpringQueryDSL来配合我的SpringBootV2.1.3


与此同时,我不得不求助于在服务层手工构建谓词,但解决这个谜团会很好。

发现了问题,以防有人遇到类似问题

在我的控制器方法中,我最初省略了
@querydsldpredicate
注释的
bindings
参数,让框架找到
QuerydslBinderCustomizer
实现。我假设框架将查找并找到我的Spring Data JPA存储库实现:

  public interface MyEntityRepository
    extends JpaRepository<MyEntity, Integer>, QuerydslPredicateExecutor<MyEntity>, QuerydslBinderCustomizer<QMyEntity> {

    @Override
    default void customize(QuerydslBindings bindings, QMyEntity myEntity) {
        ... // my bindings customizations
}
因此,该框架只需获取给定域类型的第一个repo实例,如果它没有实现
QuerydslBinderCustomizer
,就放弃了,不再继续寻找。当然,最好每个实体类型只有一个回购类。然而,在我们的例子中,遗留类仍在其他地方使用,可能还没有被删除。此外,我希望在不同的类中保持此实现和旧实现的分离也是有原因的。所以,在我的例子中,取决于首先找到的是哪个实例,事情要么有效,要么无效。通过在控制器方法注释的
bindings
arg中显式指定customizer存储库类,我解决了以下问题:

    @GetMapping("/xyz")
    public List<MyEntity> findMyEntitiesByPredicate(
        @QuerydslPredicate(root = MyEntity.class, bindings = MyEntityRepository.class) Predicate predicate, ...) {...}
@GetMapping(“/xyz”)
公共列表findMyEntitiesByPredicate(
@QuerydslPredicate(root=MyEntity.class,bindings=MyEntityRepository.class)谓词谓词,…{…}
    @GetMapping("/xyz")
    public List<MyEntity> findMyEntitiesByPredicate(
        @QuerydslPredicate(root = MyEntity.class, bindings = MyEntityRepository.class) Predicate predicate, ...) {...}