我的项目使用Spring Boot 2.1.3,Java8, QueryDsl 4.2.1.(是一个成熟的关键项目,将SB版本升级到最新的2.4.4目前还不可行。)
最近,我添加了Spring Data web支持,以简化将请求查询参数绑定到我的Spring Data JPA存储库方法中使用的QueryDsl搜索谓词的过程——在web控制器方法中使用@QuerydslPredicate
注释。由于能够为特定属性或整类属性定制绑定,这似乎很管用……直到我们发现搜索会随机停止。
经过一些调查,我注意到有时在应用程序启动后,在调用期望填充谓词的控制器方法之前,框架不会调用Spring Data JPA存储库上的< code>customize方法实现。如果查询有任何依赖于定制绑定的搜索参数,查询将会失败。但最疯狂的是。我会停止并重启应用程序(不做任何改变!),一切都将开始工作,相同的查询将产生预期的结果。
值得注意的是,在调试模式(在IntelliJ IDEA中)重新启动似乎可以正确加载所有内容(大多数情况下,但我认为并非总是如此),并且“自定义”方法中的代码将被执行。我会多次停止并重新启动应用程序,而无需更改任何内容或重新构建。有时它会起作用,有时它不会!相同的查询/请求。在不同环境中,行为是不一致的。我已确保使用提供的
作用域声明 QueryDSL APT 依赖项(用于 Q 类型的注释处理和代码生成),而不是打包到 JAR 中。
我看到Spring QueryDsl库始终包含在类路径上并且可用,这应该确保支持@QuerydslPredicate
注释自动启用 - 每个文档。看起来 - 取决于启动时的随机内容 - 框架找不到所需域类型(我的实体类)的定制器实现。
一旦成功了,就成功了。但我永远无法确定一旦应用程序停止并重新启动,它是否会被启用。有人知道是什么导致了这种奇怪的行为吗?也许是版本不匹配?Spring Data Web支持QueryDsl的一个bug?也许,我应该尝试使用一个不同的,早期版本的spring querydsl来搭配我的Spring Boot v2.1.3吗?
与此同时,我不得不求助于在服务层手工构建谓词,但最好能解决这个谜。
发现问题,以防有人遇到类似的问题...
在我的控制器方法中,我最初省略了< code>@QuerydslPredicate注释的< code>bindings参数,让框架找到< code > 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
}
不幸的是,同一个实体类还有另一个遗留存储库接口。显然,第二个存储库有不同的名称,并且没有实现QuerydslPredicateExector
,我错误地认为这会使框架完全忽略它,并且总是根据上述接口找到正确的实现。显然,Spring不是这样做的,这可能是框架中的一个小缺陷。以下是Spring的QuerydslBindingsFactory
中的片段:
.orElseGet(() -> repositories.flatMap(it -> it.getRepositoryFor(domainType))//
.map(it -> it instanceof QuerydslBinderCustomizer ? (QuerydslBinderCustomizer<EntityPath<?>>) it : null)//
.orElse(NoOpCustomizer.INSTANCE));
因此,该框架简单地获取给定域类型的第一个repo实例,如果它没有实现< code > QuerydslBinderCustomizer ,就放弃继续寻找。当然,每个实体类型最好只有一个回购类。然而,在我们的例子中,legacy类仍然在其他地方使用,可能还没有被删除。此外,我有理由将这个和旧的实现分开放在不同的类中。因此,在我的例子中,根据哪个实例先被发现,事情要么成功,要么失败。通过在控制器方法的注释的< code>bindings arg中显式指定定制器存储库类,我修复了这个问题:
@GetMapping("/xyz")
public List<MyEntity> findMyEntitiesByPredicate(
@QuerydslPredicate(root = MyEntity.class, bindings = MyEntityRepository.class) Predicate predicate, ...) {...}
我有一个嵌入jetty服务器的Gradle Java项目。我想为同一个项目启用web应用程序支持。 Intellij IDEA帮助说明如何在下面的链接中为现有项目启用。https://www.jetbrains.com/help/idea/2016.1/enabling-web-application-support.html#d1788100e258 但是这个过程使用了Intellij IDEA
我在Hibernate4.0.1中遇到了本地查询问题。我有查询工作在数据库控制台,但不是在应用程序。我有: 名为“case”的表有两列指向同一个表--名为“cost”的表,其列为“value”。我的查询如下所示: 有人提到,'value'不是列的专有名称。这是真的,事实上这个列不是名为'value',而是有点不同。我的严格合同禁止发布任何关于代码的信息。我必须尽可能地释义它,所以我在fly中重命名
我正在尝试为一个新的Java项目启用Web应用程序支持。我正在遵循以下支持页面中提到的步骤。 我是不是漏掉了什么?
我发现Android应用程序非常奇怪的错误,而在Android设备中安装应用程序时具有给定的流程。 > 已从Play商店(旧版)安装该应用程序。 启动应用程序(现在我在主屏幕上,即< code>HomeActivity)。 现在,我通过安装最新版本(正在生产版本,尚未发布到playstore)升级了应用程序。 单击启动器图标,等待主屏幕显示,然后按菜单按钮将应用程序置于后台。 现在,单击启动器图标
我正在寻找一个解决方案来实现来自Spring-引导应用程序的GraphQL api调用,查询模式如下: 查询{ getDetailsByRefNumber(RefNumbers: “”) { } } 有人知道如何实现这一点吗?通过以下链接之一,但未找到任何解决方案 有没有基于java的Graphql客户端可以从Java代码调用graphql服务器?
使用仅应用程序访问令牌,访问令牌(jwt)如下所示 然后使用curl 退换商品 如果使用用户登录访问令牌,它可以正常工作。 此外,我不能使用“https://graph.microsoft.com/v1.0/drives/{upn}/root/,因为API是“https://{tenant}-my”的子集。sharepoint。com/U api/v2.0/”。 应用程序应该如何访问令牌读取One